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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

记得不支持多继承是因为,如过支持,那么多个父类中如果有相同的函数,那么调用时不能确定调用哪一个
问题是不是
不是所有的类都继承了Object类吗?那么如果一个类的父类中,有与Object类中相同的函数,那调用时不是也不知道该调用哪个函数吗?设计java的时候应该是考虑到这点了,有人知道这种情况,java是如何处理的吗?

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1 赞一个!

查看全部评分

6 个回复

倒序浏览
一、不知道你从哪里记得java不支持多继承是因为你说的那个原因。但我确信不是你说的那样的!
理由我可以说两条:
     1.C++支持多继承,C++都可以处理多继承带来的问题,难道比C++晚的多的JAVA就处理不了?至少它可以效仿C++。
     2.Java虽然不支持多继承,但是它有接口机制,一个类可以实现很多接口,实现接口和继承很像很像,也可以向上转型,也会从接口那里得到方法。既然接口没问题,也就可以处理多继承。

     实际上java不支持多继承是因为设计java的人看到C++程序员被多继承整的焦头烂额而做的改进。

二、你的第二个问题也不成立。父类中怎么可能有与Object相同的函数?难道父类就不是Object的子类吗?当你在一个类里定义与Object重名方法时就override了。

三、当然了,你考虑的问题也会发生:当一个类的父类和它要实现的接口有重名函数时。比如A类既要继承于B类,又要实现C接口,而B和C有一个重名方法write(),参数也一样。其实这样也很简单!你继承自B类的方法自动就填充了从C接口得到的抽象方法。A类最终还是只有一个write方法

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1 赞一个!

查看全部评分

回复 使用道具 举报
我觉得楼主理解错了,说Java不支持多继承,是指一个类不能有两个以上的父亲而不是说一个父亲不能有多个儿子

那么如果一个类的父类中,有与Object类中相同的函数,那调用时不是也不知道该调用哪个函数吗?
如果有两个父亲,而且两个父亲都有同样的函数,那子类就不知道该找哪个父亲要这个函数了,你说的这点就是为什么不会有多继承
可是如果有两个类中的东西都是只有一部分我想用,而不是想用它们全部的,该怎么办呢,Java就用多实现来弥补这点的不足

好好看视频,这些东西视频里都有讲的
因为接口中的函数都是空的,什么也没有,不会出现相同函数不知道调用哪个接口的问题

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1 赞一个!

查看全部评分

回复 使用道具 举报
所谓继承,就是重新使用接口。
使用继承时,相当于创建了一个新类。这个新类不仅包含了现有类型的所有成员(尽管private成员被隐藏起来,且不能访问),但更重要的是,它复制了基础类的接口。也就是说,可向基础类的对象发送的所有消息亦可原样发给衍生类的对象。
继承的结局:继承最终会以创建一系列类收场,所有类都建立在统一的接口基础上。所有类最终是否都应从单独一个基础类继承,Java的回答是肯定的。单根结构中的所有对象都有一个通用接口,所以它们最终都属于相同的类型


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

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1 赞一个!

查看全部评分

回复 使用道具 举报
本帖最后由 王军行 于 2013-3-9 16:41 编辑

不是所有的类都继承了Object类吗?那么如果一个类的父类中,有与Object类中相同的函数,那调用时不是也不知道该调用哪个函数吗?设计java的时候应该是考虑到这点了,有人知道这种情况,java是如何处理的吗?
这个问题其实我觉得不是父类出现了Object中相同的函数,这不是父类复写了Object类中的函数吗?那么调用还用考虑Object的原来的函数吗?直接用父类中的就是了
我个人是这么认为的:父类覆盖了与Object类中相同的函数,有什么不对的希望高手帮忙
回复 使用道具 举报
本帖最后由 韩松范 于 2013-3-9 19:32 编辑
李辉 发表于 2013-3-9 06:29
一、不知道你从哪里记得java不支持多继承是因为你说的那个原因。但我确信不是你说的那样的!
理由我可以说 ...

关于第二点:
我是说如果有一个类较Zi,Zi继承了一个类叫Fu
class Fu
{
    String toString()
    {
         return "haha";
     }
}
那么此时,其实Zi是继承了两个类

真是的情况应该是
class Zi extends Object,Fu
{

}
如果
Zi z = new Zi();
System.out.pritln(z.toString());//这里调用的是从Object里继承的toString()方法,还是从Fu类中继承的方法?
两个方法应该是冲突的。。。。。。。

回复 使用道具 举报
韩松范 发表于 2013-3-9 19:30
关于第二点:
我是说如果有一个类较Zi,Zi继承了一个类叫Fu
class Fu

我一开始就明白你的意思,你再好好看看我给你写的!好好想想! 总之一句话,你定义的类Zi 其实只有一个toString()方法,这个toString()是从Fu类继承的,同时也是间接从Object继承的。不存在像你说的 该调用哪个的问题!当然你可以给Zi 类定义接受参数的toString方法,那它就有不止一个toString方法了,这是方法重载
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马