java中的这两个事实
事实1
“ java中的每个类默认扩展java元类Object
”
和
事实2
“ java中不允许多重继承”在此处详细了解钻石问题Java inheritance
安静令人困惑
假设ClassB
延伸ClassA
然后根据事实1 ClassB
延伸Object
这是否意味着ClassB
同时延伸ClassA
和Object
?这是多重继承的情况吗?
如果它不是多重继承那么这两个陈述怎么不矛盾?
答案 0 :(得分:6)
“java中的每个类默认扩展java元类Object” // fact1
每个班级都延伸Object
班级,只有在他们不直接扩展任何其他班级时。
如果某个类Test
扩展了另一个Sample
类,那么Test
不会直接扩展Object
类,但是,通过超类继承Object类行为Sample
,直接扩展Object
类。
答案 1 :(得分:3)
感谢您提供事实来源。现在我可以进入一些细节。
“Head First Java 2nd edition”在第208页说:
Java中的每个类都扩展了Object
Class Object是所有类的母亲;它是所有内容的超类。
在段落中进一步说:
您编写的每个课程都会扩展对象 ,而您无需说出来。 [...]可以把它想象成你写的课程看起来像这样:
public class Dog
extends Object
{ }
[...]狗已经扩展了一些东西, Canine 。 [...]编译器将使 Canine 扩展Object。
虽然他们试图沟通的一般想法(Java中的每个类都有java.lang.Object
为 a 超类)是正确的,但他们使用了错误的术语,并且示例使用Dog
是完全错误的,这会导致您的混淆。
我编写了一个Java编译器(用于Java 1.4),我对Java语言规范非常熟悉,所以请耐心等待。
为了证明术语是“Head First Java”是错误的,我需要引用Java语言规范,这有点技术性。
但首先,我可以让您更轻松地解释如何看到这一点。
更好的定义
Java中没有明确
extend
另一个类的每个类都扩展为Object
当你写:
class Canine { }
然后编译器将其表示:
class Canine extends Object { }
但是当你写:
class Dog extends Canine { }
然后编译器发现你已经显式扩展了一个类,并且 不会改变代码的含义。
由于Head First Java第二版基于Java 5,我将使用该Java版本的Java语言规范。
extends 的含义在 section 8.1.4 of the JLS 中定义:
8.1.4超类和子类
普通类声明中的可选extends子句指定 当前类的直接超类。
Super: extends ClassType
如您所见, extends 仅指 direct 超类。在Head First Java的示例中,Dog不扩展Object,因为它的直接超类是 Canine 。只有犬扩展了对象。
他们的意思是Object是Java中所有其他类的超类。这在 JLS section 4.3.2 :
中定义4.3.2类对象
类
Object
是所有其他类的超类(第8.1节)。一个 类型Object
的变量可以包含对null
引用的引用 或者对于任何对象,无论它是类的实例还是数组 (§10)。所有类和数组类型都继承class的方法Object
,[...]
我担心你会被Head First Java第二版中出现的误导性方式所牵制。 希望已经在新版本中修复了这个版本(如果有人有,请确认/反驳),否则我们应该通知作者。
答案 2 :(得分:2)
是的,这两个陈述都是正确的。
java中的每个类都扩展了元类Object
。
仍然ClassB没有多重继承,因为在编译时java将Object
类移动一级。
现在这种方式ClassA
现在扩展Object
而不是ClassB
。
这种方式ClassB
没有多重继承,因此遵循fact2。
现在ClassB
扩展ClassA
,ClassA
扩展Object
,因此通过 MultiLEVEL继承 ClassB扩展Object
;事实1紧随其后