java mixin_理解Dart的Mixin继承机制
2019独角兽企业重金招聘Python工程师标准>>>
Dart语言集合了现代编程语言的众多优点,Mixin继承机制也是其一。但针对Java程序员来说,可能不是一下子能理解的,比如我第一次看到的时候,也迷迷糊糊了半天——这是啥玩意???
要说Mixin,可能写成MixIn会更好理解,翻译回来就是混入,当然你执意说这是一种“迷信”继承机制,那也没辙。
下面将从一个实际情景入手,对比Java和Dart的实现,以便更好理解Dart的mixin。
场景
我们先来描绘这么一个职业关系图:
职业关系图
从图中可以梳理出以下关系:
工程师类目,有软件工程师和建筑工程师师等,他们共同点都是工程师
教师类目有美术教师,IT教师等,他们共同点都是教师
而以上的工程师、教师都是社会的工作者。
那么接下来我们分别使用Java和Dart来实现这个关系类。
注意:接下来的这篇文章中为了方便表达意义,将所有类写在一个文件里面,请暂时忽略代码不规范细节。并且Dart在本文不会使用语法糖写法。
Java版本实现
从层级出发,可以写出Java版本实现如下:
//工作者
abstract class Worker {
public abstract void doWork();//工作者需要工作
}
//工程师
class Engineer extends Worker {
@Override
public void doWork() {
System.out.println("工程师在工作");
}
}
//教师
class Teacher extends Worker {
@Override
public void doWork() {
System.out.println("教师在教学");
}
}
//软件工程师
class SoftwareEngineer extends Engineer {
}
//建筑工程师
class BuildingEngineer extends Engineer {
}
//美术教师
class ArtTeacher extends Teacher {
}
//IT教师
class ITTeacher extends Teacher {
}
Dart版本实现
//工作者
abstract class Worker {
void doWork();//工作者需要工作
}
//工程师
class Engineer extends Worker {
void doWork() {
print('工程师在工作');
}
}
//教师
class Teacher extends Worker {
void doWork() {
print('教师在教学');
}
}
//软件工程师
class SoftwareEngineer extends Engineer {
}
//建筑工程师
class BuildingEngineer extends Engineer {
}
//美术教师
class ArtTeacher extends Teacher {
}
//IT教师
class ITTeacher extends Teacher {
}
从上面实现可以看出,两个实现并没什么卵区别好咩。。。。。。
嗯,目前来说确实是这样的,因为Dart也是单继承。
因为上面的场景是在是too young too simple了,下面开始扩展一些场景。
场景扩展
还是刚刚那张关系图,我们开始思考这些职业他们都具有什么能力。
于是我给这些职业虚拟了以下能力:
职业
能力
软件工程师
软件设计、修电脑
建筑工程师
手绘
美术教师
手绘、书法
IT教师
修电脑
他们的关系图如下:
通过图形或表格可以看出,软件工程师和IT教师都具备修电脑的能力,建筑工程师和美术教师都具备手绘的能力,但是这些能力都是他们特有的,不是工程师或者教师具备的能力,所以不能在他们的父类中实现。
那么这个时候我们就考虑到一个东西——接口。
以软件工程师和IT教师为例:
他们都具备修电脑的能力:
interface CanFixComputer {
void fixComputer();
}
interface CanDesignSoftware {
void designSoftware();
}
//软件工程师
class SoftwareEngineer extends Engineer implements CanFixComputer, CanDesignSoftware {
@Override
public void fixComputer() {
System.out.println("修电脑");
}
@Override
public void designSoftware() {
System.out.println("设计软件");
}
}
//IT教师
class ITTeacher extends Teacher implements CanFixComputer {
@Override
public void fixComputer() {
System.out.println("修电脑");
}
}
相当标准的实现了
我们知道Dart是没有interface这种东西的,但并不以为着这门语言没有接口,事实上,Dart任何一个类都是接口,你可以实现任何一个类,只需要重写那个类里面的所有具体方法。
我们只需要将上面的interface 修改成 abstract class,就是dart中的实现了。
但是我们发现,fixComputer这个接口被继承了两次,并且两次的实现都是一样的,这里就出现了代码重复和冗余的问题。怎么办呢?在java中我们有接口的default实现来解决这个问题(这是一个java8出现的不得已的方案。)
这个时候mixin的作用就出现了
abstract class CanFixComputer {
void fixComputer() {
print('修电脑');
}
}
abstract class CanDesignSoftware {
void designSoftware() {
print('设计软件');
}
}
//软件工程师
class SoftwareEngineer extends Engineer
with CanFixComputer, CanDesignSoftware {
}
//IT教师
class ITTeacher extends Teacher with CanFixComputer {
}
main() {
ITTeacher itTeacher = new ITTeacher();
itTeacher.doWork();
itTeacher.fixComputer();
SoftwareEngineer softwareEngineer = new SoftwareEngineer();
softwareEngineer.doWork();
softwareEngineer.fixComputer();
softwareEngineer.designSoftware();
}
可以看到,这里不再用implements,更不是extends,而是with。
而且,每个具有某项特性的类不再需要具体去实现同样的功能,接口是没法实现功能的,而通过继承的方式虽然能实现功能,但已经有父类,同时不是一个父类,又不能多继承,所以这个时候,Dart的Mixin机制就比Java的接口会高效,开发上层的只需要关心当前需要什么特性,而开发功能模块的关心具体要实现什么功能。
顺序的理解
既然是with,那应该也会有顺序的区别,
思考一个问题:如果同时with两个类,但两个类中有同样的一个方法的不同实现,那么这个时候应该使用的是哪一个类的方法?
下面以一个简单的Demo来说明这个问题:
class First {
void doPrint() {
print('First');
}
}
class Second {
void doPrint() {
print('Second');
}
}
class Father {
void doPrint() {
print('Father');
}
}
class Son1 extends Father with First,Second {
void doPrint() {
print('Son1');
}
}
class Son2 extends Father with First implements Second {
void doPrint() {
print('Son2');
}
}
main() {
Son1 son1 = new Son1();
son1.doPrint();
Son2 son2 = new Son2();
son2.doPrint();
}
那么这个程序运行后,将会在控制台输出如下:
1
2
Son1
Son2
可以看到,无论是extends、implements还是mixin,优先级最高的是在具体类中的方法。
我们稍微改一下上面的例子:
class First {
void doPrint() {
print('First');
}
}
class Second {
void doPrint() {
print('Second');
}
}
class Father {
void doPrint() {
print('Father');
}
}
class Son1 extends Father with First,Second {
}
class Son2 extends Father with First implements Second {
}
main() {
Son1 son1 = new Son1();
son1.doPrint();
Son2 son2 = new Son2();
son2.doPrint();
}
这个时候控制台输出如下:
1
2
Second
First
可以看到,其实在Son2中implements只是说要实现他的doPrint()方法,这个时候其实具体实现是First中Mixin了具体实现。
而Mixin的具体顺序也是可以从代码倒过来看的,最后mixin的优先级是最高的。
PS: dart中有个关键字 mixin 可以用来替换上面的 class,这个类表示专门用来做mixin的。
另外在mixin类中我们还以使用这样使用
mixin MusicalPerformer on Musician {
// ···
}
这个表示只有类Musician能够使用这个mixin类。
java mixin_理解Dart的Mixin继承机制相关推荐
- JavaScript大杂烩4 - 理解JavaScript对象的继承机制
JavaScript是单根的完全面向对象的语言 JavaScript是单根的面向对象语言,它只有单一的根Object,所有的其他对象都是直接或者间接的从Object对象继承.而在JavaScript的 ...
- java 判断object类型_Java 类继承机制
封装.继承.多态是面向对象的三大特征,"继承"最主要的目的是为了实现代码的可复用性.通过父类与子类的继承关系,子类继承了父类的成员函数和成员变量,提高了代码的重复利用率.同时,子类 ...
- 深入理解 Dart 中的继承和 Minxins
上一篇文章中我们详细地介绍了 Dart 中的面向对象的基础,这一篇文章中我们继续探索 Dart 中面向对象的重点和难点(继承和 Mixins).Mixins(混合)特性是很多语言中都是没有的.这篇文章 ...
- Javascript继承机制的设计思想
我一直很难理解Javascript语言的继承机制. 它没有"子类"和"父类"的概念,也没有"类"(class)和"实例" ...
- 初步理解Java的三大特性——封装、继承和多态
声明:整理自网络,如有雷同,请联系博主处理 一.封装 封装从字面上来理解就是包装的意思,专业点就是信息隐藏,是指利用抽象数据类型将数据和基于数据的操作封装在一起,使其构成一个不可分割的独立实体,数据被 ...
- 深入理解Java类型信息(Class对象)与反射机制
关联文章: 深入理解Java类型信息(Class对象)与反射机制 深入理解Java枚举类型(enum) 深入理解Java注解类型(@Annotation) 深入理解Java并发之synchronize ...
- 在java继承机制中 父类中的私有_Java中子类能继承父类的私有属性吗?
前段时间去听老师讲课的时候,老师告诉我子类是可以继承父类所有的属性和方法的.当时我是极其疑惑的,因为之前学校考试时这个考点我记得很清楚:子类只能继承父类的非私有属性和方法.老师给我的解释是这样的--先 ...
- Java基础复习——继承机制
一.写在前面 1.基本作用 代码复用,更重要的就是有了继承机制后才会有后面的"方法重写"和"多态机制". 2.语法格式 //Student类继承了Person类 ...
- java看不起c语言,为什么我感觉Java比C语言难呢?总觉得逻辑上没有C语言好理解。比如各种继承介面。包之间的关系。...
为什么我感觉Java比C语言难呢?总觉得逻辑上没有C语言好理解.比如各种继承介面.包之间的关系.以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我 ...
最新文章
- WKWebView 那些坑
- 抽成 30% 的苹果税是良心价?谷歌也学“坏”了
- 网站运营活动总结报告模板
- Zuul 2 : The Netflix Journey to Asynchronous, Non-Blocking Systems--转
- php获取xml某个节点的所有内容,怎样输出XML所有的同名节点内容?
- IDEA中SpringBoot中使用单元测试Junit方法
- typecho 去掉index.php,typecho如何去掉index.php
- Vue 消除Token过期时刷新页面的重复提示
- Python sorted() 函数
- 反向传播算法的详细解释(下)
- 总结前端常用控件和疑难杂症的解决方法
- php课后题,知到PHP语言程序设计课后习题答案
- php大m大d,ThinkPHP中M方法与D方法区别
- JAVA集合系列(1):集合的整体框架
- 推荐一款好用的取色器(仅支持windows)
- XMPP即时通讯协议使用(十)——好友关系状态
- PMP第六章:项目进度管理
- 致远互联开始向云端生态发力奔跑
- 单向流动的拓扑结构_六种基本网络拓扑结构
- 阅读源码-理解torch.utils.data、torch.utils.data.Dataset、torch.utils.data.DataLoader的工作方式