1

java中的这两个事实

事实 1

“<strong>默认情况下,java 中的每个类都扩展了 java 元类Object

事实 2

“<strong>Java 中不允许多重继承”在此处阅读有关钻石问题的更多信息 Java 继承

安静令人困惑

假设ClassBextends ClassA then 根据 fact1 ClassBextendsObject

在此处输入图像描述

这是否意味着ClassB同时扩展ClassAObject?是多重继承的情况吗?

如果不是多重继承,那么这两个陈述怎么不矛盾?

4

3 回答 3

7

“默认情况下,java 中的每个类都扩展了 java 元类 Object” //fact1

每个类都扩展Object类,前提是它们不直接扩展任何其他类

如果一个类Test扩展了另一个Sample类,那么Test不要Object直接扩展类,而是通过超类继承Object类的行为Sample,直接扩展Object类。

于 2014-04-05T13:42:55.880 回答
3

感谢您提供事实的来源。现在我可以详细介绍一下。

“Head First Java 2nd edition”在第 208 页上说:

Java 中的每个类都扩展了 Object

类对象是所有类的母亲;它是一切的超类。

在该段的后面,它说:

您编写的每个类都扩展了 Object,而您不必说出来。[...]可以把它想象成你写的一个类看起来像这样:[...] Dog已经扩展了一些东西, Canine。[...] 编译器将改为使Canine扩展 Object。public class Dogextends Object{ }

虽然他们试图交流的一般想法(Java 中的每个类都java.lang.Object作为类)是正确的,但他们使用了错误的术语,并且使用的示例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的含义在 JLS 的第 8.1.4 节中定义:

8.1.4 超类和子类

普通类声明中的可选扩展子句指定当前类的直接超类。

Super:
  extends ClassType

如您所见,extends仅指直接超类。在 Head First Java 的示例中,Dog 没有扩展 Object,因为它的直接超类是Canine。只有Canine扩展了 Object。

他们的意思是 Object 是 Java 中所有其他类的超类。这在JLS 第 4.3.2 节中定义:

4.3.2 类对象

该类Object是所有其他类的超类(第 8.1 节)。类型变量Object可以保存对null引用或任何对象的引用,无论它是类的实例还是数组(第 10 节)。所有类和数组类型都继承类的方法 Object,[...]

恐怕您会被 Head First Java 第 2 版中的误导方式所误导。希望已经在较新的版本中修复了这个问题(如果有人有,请确认/反驳),否则我们应该通知作者。

于 2014-04-05T17:04:19.767 回答
2

是的,这两种说法都是正确的。

确实,java 中的每个类都扩展了元类Object

ClassB 仍然没有多重继承,因为在编译时 java 将ObjectClass 移动了一级。

在此处输入图像描述

这种方式现在ClassA扩展Object而不是ClassB.

这种方式ClassB没有多重继承,因此遵循fact2。

现在通过MultiLEVEL Inheritance ClassB extendsClassB扩展ClassAClassA 扩展;事实1紧随其后ObjectObject

于 2014-04-05T13:40:08.430 回答