0

据说,Java 语言只支持单继承。但是,如何同时从 Object 和任何其他类继承?这不是多重继承吗?

其次,我们为什么需要继承所有 11 个 Object 方法?我几乎无法想象为什么我在 I/O 中需要它们,例如

最后,JDK 8 将为我们提供接口中的默认方法实现,如果这可能会导致 Java 中的多重继承。

如果接口 A 提供了具有默认实现的方法 a() 并且接口 B 还提供了具有另一个默认实现的 a() 方法,而我们的自定义类 C 实现了这两个接口并依赖于默认实现——那不就是Diamond of Death吗?

4

6 回答 6

8

但是,如何同时从 Object 和任何其他类继承?这不是多重继承吗?

不,这不是发生的事情。并非所有类都直接从类扩展Object。但只有继承层次结构顶层的类从Object类(隐式)扩展。层次结构中较低的其余类从Object该类扩展到超类。而且,这就是我们所说的多级继承

因此,请考虑以下层次结构:-

class A { }

class B extends A { }

在上述情况下,class A等价于class A extends Object

其次,我们为什么需要继承所有 11 个 Object 方法?我几乎无法想象为什么我在 I/O 中需要它们

我怀疑您说的意思是override继承。您不需要覆盖任何Object类的方法。是否覆盖任何方法都取决于您的要求。例如: - 您经常想要覆盖equals()方法,以便为您的实例编写自定义相等测试。在这种情况下,您还应该重写该hashCode()方法,以维护equals()and的合同hashCode()

最后,JDK 8 将为我们提供接口中的默认方法实现,如果这可能会导致 Java 中的多重继承。

如果接口 A 提供具有默认实现的方法 a() 并且接口 B 还提供具有另一个默认实现的 a() 方法,而我们的自定义类 C 实现了这两个接口并依赖于默认实现——那不就是 Diamond of Death 吗?

我无法评论这个概念,因为我还没有读到这件事。可能,我稍后会更新答案。

于 2013-02-04T17:56:30.137 回答
3

但是,如何同时从 Object 和任何其他类继承?这不是多重继承吗?

除非另有说明,否则类扩展Object. 也就是说,这个:

class A { ... }

相当于:

class A extends Object { ... }

其次,我们为什么需要继承所有 11 个 Object 方法?我几乎无法想象为什么我在 I/O 中需要它们,例如

  • equals()hashCode()用于比较和哈希表。
  • notify()wait()形成了跨线程通信的底层基础。
  • getClass()是所有反射代码的起点。

通过将它们放在 上Object,它们可以在 JVM 中的每个对象上使用。您可以获取任何对象的哈希码和类,可以检查任何两个对象之间的相等性,可以监视和通知任何对象。

如果接口 A 提供具有默认实现的方法 a() 并且接口 B 还提供具有另一个默认实现的 a() 方法,而我们的自定义类 C 实现了这两个接口并依赖于默认实现——那不就是 Diamond of Death 吗?

正如在 SO 上的另一个问题中所解释的那样(实际上只是对“jdk8 默认方法”的一次搜索):

为了解决多重继承问题,实现两个接口的类为相同的方法名称和签名提供默认实现,必须提供该方法的实现。

因此,该类必须提供自己的实现,可能委托给默认方法之一。

于 2013-02-04T18:02:45.667 回答
1

您对“死亡钻石”的看法是正确的,但是...

这是 D 实现接口 C 和 B 并且两者都实现 A 的情况。此外,在两个或多个这些接口中定义了默认方法。

在此处输入图像描述

在 Java 8 中,他们定义了一种对两个默认方法定义进行排序的方式。

我记得,如果 A 和 B 都定义了默认方法,那么 D 使用 B 的版本,因为它在类层次结构中较低。

如果 B 和 C 都定义了相同的默认方法,则存在冲突,D 将需要自己实现该方法,尽管它可以通过回调在 B 或 C 中实现的版本来实现(或者它可以有条件并使用两者都在不同的情况下)。

interface A {  } 
interface B implements A { void m() default {println("In A");} } 
interface C implements A { void m() default {println("In B");} } 
}  
class D implements B, C {  
    public void m() { println("In D"); B.super.m(); } 
} 

但是您可以访问 Oracle 的有关 Java 8 新特性的页面并阅读所有相关信息。我通过谷歌搜索“Java 8 新特性”到达了那里。在http://cr.openjdk.java.net/~briangoetz/lambda/Defender%20Methods%20v4.pdf找到了我的想法

于 2013-02-04T18:04:53.713 回答
0

您继承自一个类,该类继承自对象。Java 不允许您从两个不同的类链继承。但是,解决此问题的方法是使用接口。

于 2013-02-04T17:57:12.527 回答
0

但是,如何同时从 Object 和任何其他类继承?

你不能这样做,你听错了。

其次,我们为什么需要继承所有 11 个 Object 方法?我几乎无法想象为什么我在 I/O 中需要它们,例如

不知道你在说什么。

如果接口 A 提供具有默认实现的方法 a() 并且接口 B 还提供具有另一个默认实现的 a() 方法,而我们的自定义类 C 实现了这两个接口并依赖于默认实现——那不就是 Diamond of Death 吗?

对JDK8一无所知,但是您已经可以在两个接口中实现具有相同名称/类型签名的方法,这可能不合逻辑,但Java允许这样做。

于 2013-02-04T17:58:53.330 回答
0

首先,Java 中的一切都是对象或原语,所以这里没有问题。Object 是层次结构顶部的类。

目前,您已经可以将多个接口应用到 Java - 然后您编写您的实现。我想在 Java 8 中,如果你定义了你的接口,那么你就有了实现。如果不是,则使用一些默认值。如果定义了多个默认值(或方法由多个接口声明)- 不使用默认值。这可以很简单。

于 2013-02-04T17:59:30.293 回答