先来看看多继承会带来的问题,继承容易导致钻石危机(也称棱形问题),一幅图来说说明:
假设 类A 中有一个public方法 fun(),然后 类B 和 类C 同时继承了 类A,在 类B 或 类C 中各自对方法 fun()进行了覆盖,这时 类D 通过多继承同时继承了 类B 和 类C,这样便导致钻石危机了,程序在运行的时候对于方法 fun()该如何判断?
总结如下,主要有两个方面:
(1)如果在一个子类继承的多个父类中拥有相同名字的实例变量,子类在引用该变量时将产生歧义,无法判断应该使用哪个父类的变量。 (2)如果在一个子类继承的多个父类中拥有相同方法,子类中有没有覆盖该方法,那么调用该方法时将产生歧义,无法判断应该调用哪个父类的方法。 在接口中不能有实例变量,只能有静态的常量,不能有具体的方法(包含方法体),只能有抽象方法,因此也就摒弃了多继承的缺点。 对于一个类实现多个接口的情况,因为接口只有抽象方法,具体方法只能由实现接口的类实现,在调用的时候始终只会调用实现类的方法(不存在歧义),因此不存在 多继承的第二个缺点;而又因为接口只有静态的常量,但是由于静态变量是在编译期决定调用关系的,即使存在一定的冲突也会在编译时提示出错;而引用静态变量一般直接使用类名或接口名,从而避免产生歧义,因此也不存在多继承的第一个缺点。 对于一个接口继承多个父接口的情况也一样不存在这些缺点。
但是java中可以用接口和内部类的方式来间接达到多继承的效果:
//这是通过接口来间接实现多继承的
interface HowEat{
public abstract String howeat();
}
class Chenken implements HowEat{
public String howeat(){
return "chicken: fry it ";
}
}
class Orange implements HowEat{
public String howeat(){
return "orangr: make it juice";
}
}
//这是通过内部类来实现的
class Father{
public void output(){
System.out.println("father");
}
}
class Mother{
public void output(){
System.out.println("mather");
}
}
class son{
class Father_son extends Father{
}
class Mother_son extends Mother{
}
public void father(){
(new Father_son()).output();
}
public void mather(){
(new Mother_son()).output();
}
}