A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 孙政 于 2013-5-6 17:13 编辑

为什么java搞单继承,多继承有什么坏处?用什么可以弥补这些坏处?求解答啊。。。

评分

参与人数 1技术分 +1 收起 理由
田磊阳 + 1

查看全部评分

8 个回复

倒序浏览
之所以没有多继承,是因为多继承容易引起混乱。比如一个相同的方法两个父类都有,子类到底是继承哪个叻?
java是通过实现多个接口来弥补不能多继承的缺陷的。

评分

参与人数 1技术分 +1 收起 理由
田磊阳 + 1

查看全部评分

回复 使用道具 举报
同楼上的。多继承是容易让代码混乱的,假如:继承的;两个父类中有相同名称的变量、函数,那在子类中调用的时候,就搞不清楚是那个父类的成员了。继承是为了更好的使用父类中的成员,能够将子类中的共性提取出来,所以继承需要是但继承的。但是子类需要继承多个父类的话,这时候就有了接口,可以使用接口来实现多继承,而且是可以实现多接口的。

评分

参与人数 1技术分 +1 收起 理由
田磊阳 + 1

查看全部评分

回复 使用道具 举报
多继承虽然能使子类同时拥有多个父类的特征,但是其缺点也是很显著的,主要有两方面:
(1)如果在一个子类继承的多个父类中拥有相同名字的实例变量,子类在引用该变量时将产生歧义,无法判断应该使用哪个父类的变量。
(2)如果在一个子类继承的多个父类中拥有相同方法,子类中有没有覆盖该方法,那么调用该方法时将产生歧义,无法判断应该调用哪个父类的方法。

在接口中不能有实例变量,只能有静态的常量,不能有具体的方法(包含方法体),只能有抽象方法,因此也就摒弃了多继承的缺点。
对于一个类实现多个接口的情况,因为接口只有抽象方法,具体方法只能由实现接口的类实现,在调用的时候始终只会调用实现类的方法(不存在歧义),因此不存在 多继承的第二个缺点;而又因为接口只有静态的常量,但是由于静态变量是在编译期决定调用关系的,即使存在一定的冲突也会在编译时提示出错;而引用静态变量一般直接使用类名或接口名,从而避免产生歧义,因此也不存在多继承的第一个缺点。
对于一个接口继承多个父接口的情况也一样不存在这些缺点。

评分

参与人数 1技术分 +1 收起 理由
田磊阳 + 1

查看全部评分

回复 使用道具 举报
单继承:一个子类只能有一个直接父类。
class A
{
}
class B
{
}
class C extends A
{
}
多继承:一个子类可以有多个直接父类。
class A
{
}
class B
{
}
class C extends A,B
{
}

Java中不直接使用多继承的原因是:会产生调用的不确定性。比如:class A和class B中都有一个Show()方法时,使用class C创建对象后调用Show()方法不知道是调用的是类A中的还是类B的。

Java将多继承改良为多实现
一个类可以实现多个接口。
interface A
{
        public abstract void show();
}

interface B
{
        public abstract void show();
}

class Test implements A,Z  //多实现
{
        public abstract void show()
{
       
}
}

一个类在继承另一个类的同时,还可以实现多个接口!
class Q
{
        public void method()
        {
               
}
}
class Test2 extends Q implements A,z
{

}
接口的出现,避免了java单继承的局限性。因为一个类只能继承另一个类,但是同时可以实现多个接口。

评分

参与人数 1技术分 +1 收起 理由
田磊阳 + 1

查看全部评分

回复 使用道具 举报
1,子父类关系本来是通过从下往上把共性抽取出来,形成父类,这就在一定程度上决定了父类(共性)的的唯一性。
2,子类继承父类是在父类的基础上增加自己的特定功能,而且还能在一定程度上复写父类的功能。
3,子父类单继承结构清晰,不紊乱,如果多继承,那么多个父类中如果都有同名的函数,但是返回值类型却不同,那么子类继承了父类被调用后是应该返回什么类型的值呢?这就说明了多继承对于Java并不合适。

接口实现了多继承功能,接口原本全都是抽象函数组成的,多实现后,如果有同名函数问题,那就在实现接口的时候指出你所实现的接口方法是哪个父类接口的方法,实现的时候加上父类接口的名字。
回复 使用道具 举报
这么多回答了 给你一个最全的答案  网上查阅  
多继承虽然能使子类同时拥有多个父类的特征,但是其缺点也是很显著的,主要有两方面:
(1)如果在一个子类继承的多个父类中拥有相同名字的实例变量,子类在引用该变量时将产生歧义,无法判断应该使用哪个父类的变量。例如:
           类ClassA:

public class ClassA {
       protected int varSame = 0;
}
  
           类ClassB:

public class ClassB {
        protected int varSame = 1;
}
  
           子类ClassC:(假设允许类与类之间多继承)

           public class ClassC extends ClassA, ClassB {
                   public void printOut() {
                           System.out.println(super.varSame);
                   }
                   public static void main(String[] args) {
                           ClassC classC = new ClassC();
                           classC.printOut();
                   }
           }
  

           上面程序的运行结果会是什么呢?输出0还是1?
(2)如果在一个子类继承的多个父类中拥有相同方法,子类中有没有覆盖该方法,那么调用该方法时将产生歧义,无法判断应该调用哪个父类的方法。例如:
           类ClassA:

           public class ClassA {
                   public void printOut() {
                           System.out.println(0);
                   }
           }


           类ClassB:



           public class ClassB {
                   public void printOut() {
                           System.out.println(1);
                   }
           }
  
           子类ClassC:(假设允许类与类之间多继承)

public class ClassC extends ClassA, ClassB {
                   public static void main(String[] args) {
                           ClassA classA = new ClassC();
                           classA.printOut();      // -------------------------  A行
                           ClassB classB = new ClassC();
                           classB.printOut();      // -------------------------  B行
                           ClassC classC = new ClassC();
                           classC.printOut();       //-------------------------  C行
                   }
           }
  
           上面程序的运行结果会是什么呢?A、B、C三行的输出是0还是1?
正因为有以上的致命缺点,所以java中禁止一个类继承多个父类;

在接口中不能有实例变量,只能有静态的常量,不能有具体的方法(包含方法体),只能有抽象方法,因此也就摒弃了多继承的缺点。
对于一个类实现多个接口的情况,因为接口只有抽象方法,具体方法只能由实现接口的类实现,在调用的时候始终只会调用实现类的方法(不存在歧义),因此不存在 多继承的第二个缺点;而又因为接口只有静态的常量,但是由于静态变量是在编译期决定调用关系的,即使存在一定的冲突也会在编译时提示出错;而引用静态变量一般直接使用类名或接口名,从而避免产生歧义,因此也不存在多继承的第一个缺点。
对于一个接口继承多个父接口的情况也一样不存在这些缺点。
回复 使用道具 举报
  我觉得单继承不容易造成数据混乱, 如果多继承 而且这个时候父类中又有相同的元素,那让JVM执行哪一个呢?而且 接口中的都是静态常量,这样同样避免了多继承的缺点 同时也增加了完整性。 接口的实现,我觉得又从另一个方面来说弥补了 单继承所造成的不便,可以在功能上使你所创建的类更加完整。   
回复 使用道具 举报
感谢大家的回答,就不一一回复了,让我懂了这个疑问。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马