如何使Object类成为子类的超类?

13

事实1:

Java不支持多重继承。

事实2:

Object是所有其他类的超类。

如果我有一个类Parent和一个继承父类Parent的类Child

class Parent {

}

class Child extends Parent {

}

如果Java不支持多重继承,那么类Child将如何继承Object类?

这三者之间的关系是如何定义的?

选项1:

enter image description here

选项2:

enter image description here


你的事实1实际上有点过时了,而你可能从中获取事实2的文档应该明确告诉你,你的选项2才是正确的。 - Jeremy Grand
1
@Arvind “多级继承”和“多重继承”不是同一回事。Java支持“多级继承”,但C++两者都支持。 - Abhishek Keshri
1
请不要在问题中发布答案/解决方案,但如果您认为这是真正的解决方案,请随时编写新答案并将其标记为已接受。请参见https://stackoverflow.com/help/self-answer - fantaghirocco
1
@AbhishekKeshri,是的,你可以 - 只需在下面使用答案框即可。所有“自我回答”所做的就是在问题字段上显示一个答案框。但是你真的需要发布答案吗?似乎已经有一个完美的答案了,而你也已经接受了它。 - Ant P
1
@AntP 我会删除 Solution 部分。你的论点很有道理。 - Abhishek Keshri
显示剩余16条评论
10个回答

26

选择第二个选项。如果你定义了一个超类,那么它将成为你的类的直接超类。如果你没有定义一个,Object将成为直接超类。

class Parent {

}

class Child extends Parent {

}

等价于

class Parent extends Object {

}

class Child extends Parent {

}

因此,虽然Object是所有类的超类,但在您到达Object之前,类层次结构中可能会有一些步骤。它并不是所有类的直接超类。


“class Child” 不也会继承 “Object” 吗?如果可能的话,它会是 “class Child extends Parent, Object”(不知道内部是否有这种方式!!!)? - Abhishek Keshri
6
不。子类并不是通过父类继承 Object。 - Max Vollmer

9

Object可能不是直接父类,但它总是超级父类。

Child extends Parent
Parent extends Object

 |
 V

Child [indirectly] extends Object

@AbhishekKeshri 如果情况1是正确的,我们将会遇到选择子类方法的问题(因为ObjectParent extends Object都具有相同的方法集,包括equalshashCode等)。 - Andrew Tobilko

7

JavaDoc说:

Object类是类继承体系的根。...

如果一个类没有使用关键字extends声明扩展任何其他类,则通过隐式从Object继承。

文档说:

在没有任何其他显式超类的情况下,每个类都是Object的子类。

请参阅JLS,第8.1.4章中的示例8.1.4-1"直接超类和子类"

它表明一个 class Point { int x, y; } "是 Object 的直接子类"。
此外,文档还说:

类可以派生自派生自类的类,依此类推,最终派生自顶层类 Object。这样的类被称为是从所有继承链中向后延伸到 Object 的所有类中下降的。

JLS 简明而正式地说明了这一点:

子类关系是直接子类关系的传递闭包。

因此,class Object 是所有类的超类。
但文档也说:

除了没有超类的 Object 外,每个类都有一个且仅有一个直接超类(单继承)。

继续以示例为例,class ColoredPoint extends Point { int color; } "是 class Point 的直接子类。"。通过传递关系,它是 class Object 的(非直接)子类。

总结:
Object是任何其他类的直接超类或者通过传递关系成为最后一个超类。

回答问题:

  • Java不支持多继承:它提供了一种传递方式的单一继承。每个类只直接扩展一个超类。
  • 关系如何:类Parent对应于JLS示例中的类Point,而类Child对应于类ColoredPoint。只有选项2显示了这种关系。

5

这是一个有趣的讨论。我认为应该选择第二个选项。如果您尝试以下代码:

public static void main(String []args){
      Parent p=new Parent();
      Class c= p.getClass();

      Child child =new Child();
      Class c1= child.getClass();
      System.out.println(c.getSuperclass());
      System.out.println(c1.getSuperclass());

 }

您将得到以下输出:
class java.lang.Object 
class Parent

使用以下代码解决了我的疑惑:Class child_super = c1.getSuperclass(); System.out.println(child_super.getSuperclass()); - Abhishek Keshri

3

Java中没有多重继承,这意味着一个类只能继承1个类,即只有一个直接基类。但是一个类可以有很多祖先:子类的祖先是父类和Object类,它们是"super"类。

Object --> Parent --> Child
                  --> OtherChild

Relation: 1 --> N

避免像C++中的多重继承那样,原因是其中存在歧义:
假设多重继承的伪代码:
class A : Comparable
class B : Comparable

class Child : A, B {

    @Override A? B?
    int compareTo(Child rhs) { ... super.compareTo ? ... }
}

A a = new Child();
B b = new Child();
a.compareTo(b);

1
为什么我们要关心覆盖哪个方法,即使签名相同?覆盖只意味着我们不满意父类的行为并想实现自己的行为。问题在于,当我们调用child.compareTo(anotherChild)而没有覆盖时会发生什么(我们将调用哪个方法?) - Andrew Tobilko
1
@AndrewTobilko说得好:“compareTo(a); compareTo(b), compareTo(child)”。实际上,我并不想在问题的范围之外谈论多重继承(和接口)。只是多重继承并不意味着有一个祖先线; 相反,单一继承意味着每个类只有一个(代码承载)父类。我也没有处理接口中的默认方法。 - Joop Eggen

3

选项2,因为每个对象都继承了Object.class方法。


3
正确答案是选项2。任何Java类都继承其父类的所有属性。换句话说,

类A继承类B, 类B继承类C, 类C继承类D。

类X继承A -> 这意味着A继承了B、C和D中的所有protected/package/public字段。

在你的例子中,Child类继承了Parent类的属性,但也以传递模式继承了Object类的属性。


3

来自Object类

public class Object
Object类是Java类层次结构的根。
每个类都将Object作为其父类。
所有对象(包括数组)都实现了该类的方法。

这意味着每个Java类在层次结构中都将Object作为根,但不一定是其直接父类。


3
首先,使用Java 8,可以通过接口的默认方法实现多继承
其次,在'选项2'中正确表示了关于Object类的理解。但是,这不是多重继承,而是多级继承。'选项1'是多重继承。
请查看链接以了解更多信息。

2

选项2:Object是所有其他类的超类,但Object可能不是一个类的直接超类。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接