前言
Java有两种机制允许多个类型的实现来进行扩展:接口和抽象类。抽象类即用abstract关键字修饰的类,它的特点是可以存在抽象方法,也可以存在普通方法;接口是用interface关键字修饰的,在Java 8之前只能有抽象方法,在Java 8中允许使用default关键字修饰的普通方法存在,在结构上和抽象类类似,但是抽象类有构造方法的,虽然不能直接实例化,接口就没有。
Java的单继承多实现
接口优于抽象类的最主要原因就是Java是单继承的,在一定程度上限制了扩展性,限制了它们作为类型定义的使用,我们不能保证在编程后续过程中是否需要进行扩展,所以不会轻易使用抽象类来进行扩展。
接口的存在就很好的解决了上面的问题,Java可以通过接口多实现。现有的类可以很容易地实现一个新的接口进行扩展。 你只需添加所需的方法(如果尚不存在的话),并向类声明中添加一个 implements
子句。 例如,当 Comparable
, Iterable
, 和 Autocloseable
接口添加到 Java 平台时,很多现有类需要实现它们来加以改进。 一般来说,现有的类不能改进以继承一个新的抽象类。 如果你想让两个类继承相同的抽象类,你必须把它放在类型层级结构中的上面位置,它是两个类的祖先。 不幸的是,这会对类型层级结构造成很大的附带损害,迫使新的抽象类的所有后代对它进行子类化,无论这些后代类是否合适。
接口是定义混合类型(mixin–mix in混入)的理想选择。 一般来说,mixin 是一个类,除了它本身的“主类型”之外,还可以声明它提供了一些可选的行为。 例如,Comparable
是一个类型接口,它允许一个类声明它的实例相对于其他可相互比较的对象是有序的。 这样的接口被称为类型,因为它允许可选功能被“混合”到类型的主要功能。简单点就是接口A能根据需要同时继承接口B和接口C成为混合类型; 抽象类不能用于定义混合类,这是因为它们不能被加载到现有的类中:一个类不能有多个父类,并且在类层次结构中没有合理的位置来插入一个类型。
接口允许构建非层级类型的框架。 类型层级对于组织某些事物来说是很好的,但是其他的事物并不是整齐地落入严格的层级结构中。 例如,假设我们有一个代表歌手的接口,和另一个代表作曲家的接口:
public interface Singer {
AudioClip sing(Song s);
}
public interface Songwriter {
Song compose(int chartPosition);
}
在现实生活中,一些歌手也是作曲家。 因为我们使用接口而不是抽象类来定义这些类型,所以单个类实现歌手和作曲家两个接口是完全允许的。 事实上,我们可以定义一个继承歌手和作曲家的第三个接口,并添加适合于这个组合的新方法:
public interface SingerSongwriter extends Singer, Songwriter {
AudioClip strum();
void actSensitive();
}
使用默认方法可以提供实现帮助多多少少是有些限制的。 尽管许多接口指定了 Object
类中方法(如 equals
和 hashCode
)的行为,但不允许为它们提供默认方法。 此外,接口不允许包含实例属性或非公共静态成员(私有静态方法除外)。 最后,不能将默认方法添加到不受控制的接口中。
骨架实现类
在Effective Java中提到了一个所谓的骨架实现类,理解起来总是怪怪的:使得具体子类只专注于自身的特定方法实现,忽略自身不会提供的方法(对于自身的冗余方法).简单说就是没必要一个个实现接口的所有方法,要调用就调用骨架类的。Java源码中AbstractCollection实现了Collection接口,List接口继承自Collection接口,AbstractList又继承了AbstractCollection类,并且实现了List接口。而这里ArrayList不允许忽略任何list接口的方法,必须自己去小心实现每个方法.当有某类只继承AbstractList,那就方便了,只要改写需要改写的部分,不需要使用或者修改的地方可以直接复用骨架实现类的实现。
还有一个用内部类模拟Java多继承:
儿子是如何利用多重继承来继承父亲和母亲的优良基因。
首先是父亲Father和母亲Mother:
public class Father {
public int strong(){
return 9;
}
}
public class Mother {
public int kind(){
return 8;
}
}
重头戏在这里,儿子类Son:
public class Son {
/**
* 内部类继承Father类
*/
class Father_1 extends Father{
public int strong(){
return super.strong() + 1;
}
}
class Mother_1 extends Mother{
public int kind(){
return super.kind() - 2;
}
}
public int getStrong(){
return new Father_1().strong();
}
public int getKind(){
return new Mother_1().kind();
}
}
儿子继承了父亲,变得比父亲更加强壮,同时也继承了母亲,只不过温柔指数下降了。这里定义了两个内部类,他们分别继承父亲Father类、母亲类Mother类,且都可以非常自然地获取各自父类的行为,这是内部类一个重要的特性:内部类可以继承一个与外部类无关的类,保证了内部类的独立性,正是基于这一点,多重继承才会成为可能。
参考文章:
https://blog.csdn.net/jiafu1115/article/details/6736063
https://www.cnblogs.com/qlky/p/7350740.html