【问题标题】:Class extending more than one class Java?类扩展不止一个类Java?
【发布时间】:2013-02-14 11:11:41
【问题描述】:

我知道一个类可以实现多个接口,但是可以扩展多个类吗?例如,我希望我的班级同时扩展 TransformGroup 和我创建的班级。这在Java中可能吗? class X extends TransformGroup extends Yclass X extends TransformGroup, Y 两个语句都收到错误。如果不可能,为什么? TransformGroup 扩展了 Group 但我猜它也扩展了 Node 因为它继承了 Node 的字段,并且可以在需要 Node 对象的地方传递它。此外,与 Java 中的所有类一样,它们扩展了 Object 类。那么为什么不能扩展一个以上的类呢?

TransformGroup inheritance

那么,如果可以的话,正确的方法是什么?如果没有,为什么以及如何解决这个问题?

【问题讨论】:

  • 为什么不试一次?
  • 多重继承在Java中没有实现,以避免一个称为Dreaded Diamond的问题(和其他原因)由多重和分层继承引起的(一起使用) 就像 C++ 等其他语言一样。所以简而言之,你不能使用多个扩展。

标签: java class inheritance subclass multiple-inheritance


【解决方案1】:

在 Java 中不允许多重继承。作为设计决策,它被排除在语言之外,主要是为了避免循环依赖。

场景 1: 如您所知,Java 无法实现以下操作:

public class Dog extends Animal, Canine{

}

场景 2: 但是以下情况是可能的:

public class Canine extends Animal{

}

public class Dog extends Canine{

}

这两种方法的区别在于,第二种方法有一个明确定义的父类或super 类,而第一种方法中的super 类是不明确的。

考虑AnimalCanine 是否都有方法drink()。在第一种情况下,如果我们调用Dog.drink(),会调用哪个父方法?在第二种情况下,我们知道调用Dog.drink() 将调用Caninedrink 方法,只要Dog 没有覆盖它。

【讨论】:

  • 好的,但是怎么样,例如TransformGroupcs.indiana.edu/classes/jett/dgerman/2005/html-javadoc/javax/… 它继承了 NodeGroup 的字段
  • @BujancaMihai 很高兴我能帮上忙。如果您有任何其他问题,请告诉我。
  • 不幸的是,您在 Java(和其他语言)的设计中遇到了限制。祝你好运。有很多方法可以解决这个问题。最好的可能是对象的组合。
  • @KevinBowersox 好的,但现在我遇到了另一个问题。我有一个类A 必须继承自JFrame,还有一个类B 应该由A 扩展,但不应扩展JFrame。我需要在AB 类中使用代码吗?
  • 来自user3464196 的评论: @KevinBowersox 这很酷,但是当没有遗产的可能性时?例如:public class KeepAlive extends Observable, TimerTask {}
【解决方案2】:

不,这在 java 中是不可能的(也许在 java 8 中它会可用)。除非您在树中延伸。 例如:

class A
class B extends A
class C extends B

【讨论】:

    【解决方案3】:

    在 Java 中,仅对接口的实现(类)不允许多重继承:

    interface A extends B, C
    

    例如MouseInputListener 扩展了 MouseListener 和 MouseMotionListener

    当然,一个类可以实现多个接口:

    class X implements A, F
    

    【讨论】:

      【解决方案4】:

      类不能实现多重继承,可以通过接口实现,但类不行。它是由java语言设计的。看看 James gosling 的评论。

      James Gosling 于 1995 年 2 月提出了一个想法,说明为什么要使用多个 Java 不支持继承。

      JAVA 省略了许多很少使用、难以理解、令人困惑的特性 根据我们的经验,C++ 带来的痛苦多于好处。这 主要由运算符重载组成(尽管它确实有 方法重载)、多重继承和广泛的自动 强制。

      【讨论】:

        【解决方案5】:

        Java 中没有多重继承的概念。只能实现多个接口。

        【讨论】:

          【解决方案6】:


          假设 B 和 C 覆盖继承的方法和它们自己的实现。现在 D 使用多重继承继承了 B 和 C。 D 应该继承被覆盖的方法。问题是将使用哪个被覆盖的方法?它来自B还是C?这里我们有一个歧义。为了排除这种情况,Java 中没有使用多重继承。

          【讨论】:

          • 这只是借口之一。在其他语言中,歧义会导致错误。 java 不能支持多重继承有什么原因吗?
          【解决方案7】:

          Java 没有提供多重继承。
          当您说 A 扩展 B 时,这意味着 A 扩展 B 并且 B 扩展 Object。
          这并不意味着 A 扩展 B、Object。

          class A extends Object
          class B extends A

          【讨论】:

            【解决方案8】:

            java不支持多重继承,但是你可以这样做

            class X
            {
            }
            class Y extends X
            {
            }
            class Z extends Y{
            }
            

            【讨论】:

              【解决方案9】:

              给出的大多数答案似乎都假设我们希望继承的所有类都是由我们定义的。

              但是如果我们没有定义其中一个类,即我们无法更改其中一个类继承自什么,因此无法使用已接受的答案,那么会发生什么?

              答案取决于我们是否至少定义了一个类。即在我们想要继承的类列表中存在一个类A,其中A是我们创建的。

              除了已经接受的答案之外,我还提出了多继承问题的另外 3 个实例以及每个实例的可能解决方案。

              继承类型 1

              好吧,假设你想要一个类C 来扩展类AB,其中B 是在其他地方定义的类,但A 是由我们定义的。我们可以做的是把A变成一个接口,然后类C可以在扩展B的同时实现A

              class A {}
              class B {} // Some external class
              class C {}
              

              变成

              interface A {}
              class AImpl implements A {}
              class B {} // Some external class
              class C extends B implements A
              

              继承类型2

              现在假设你有两个以上的类要继承,同样的想法仍然成立——除了一个类之外的所有类都必须由我们定义。假设我们希望类A 继承自以下类,BC、...X 其中X 是我们外部的类,即在其他地方定义的类。我们采用相同的想法,将除最后一个以外的所有其他类转换为接口,然后我们就可以拥有:

              interface B {}
              class BImpl implements B {}
              interface C {}
              class CImpl implements C {}
              ...
              class X {}
              class A extends X implements B, C, ...
              

              继承类型 3

              最后,还有一种情况是你只有一堆类要继承,但它们都不是你定义的。这有点棘手,但可以通过使用delegation 来实现。委托允许类A 伪装成其他类B,但是任何对A 的调用对B 中定义的某些公共方法,实际上是委托对B 类型对象的调用,结果是回来。这使得A 类成为我所说的Fat class

              这有什么帮助?

              嗯,很简单。您创建一个接口,指定您想要使用的外部类中的公共方法,以及您正在创建的新类中的方法,然后您让新类实现该接口。这可能听起来令人困惑,所以让我解释一下。

              最初我们有以下外部类 BCD、...、X,我们希望我们的新类 A 继承自所有这些类。

              class B {
                  public void foo() {}
              }
              
              class C {
                  public void bar() {}
              }
              
              class D {
                  public void fooFoo() {}
              }
              
              ...
              
              class X {
                  public String fooBar() {}
              }
              

              接下来我们创建一个接口A,它公开了之前在类A中的公共方法以及来自上述类的公共方法

              interface A {
                  void doSomething(); // previously defined in A
                  String fooBar(); // from class X
                  void fooFoo(); // from class D
                  void bar(); // from class C
                  void foo(); // from class B
              }
              

              最后,我们创建一个类AImpl,它实现了接口A

              class AImpl implements A {
                  // It needs instances of the other classes, so those should be
                  // part of the constructor
                  public AImpl(B b, C c, D d, X x) {}
                  ... // define the methods within the interface
              }
              

              你有它!这是一种伪继承,因为 A 类型的对象不是我们开始使用的任何外部类的严格后代,而是公开了一个接口,该接口定义了与这些类中相同的方法。

              您可能会问,为什么我们不只是创建一个定义我们想要使用的方法的类,而不是定义一个接口。即为什么我们没有一个类A,它包含我们想要继承的类的公共方法?这样做是为了减少coupling。我们不希望使用A 的类不得不过度依赖A 类(因为类往往会发生很大变化),而是依赖于接口A 中给出的承诺。

              【讨论】:

                【解决方案10】:

                Java 不允许扩展多个类。

                假设 C 类扩展了 A 类和 B 类。然后如果假设 A 和 B 类具有相同名称的方法(例如:method1())。考虑代码:

                C obj1 = new C(); obj1.method1(); - 这里 JVM 不知道它需要访问哪个方法。因为A类和B类都有这个方法。所以我们让 JVM 进退两难,这就是为什么从 Java 中移除多重继承的原因。正如所说,实现多个类将解决这个问题。

                希望这有帮助。

                【讨论】:

                  【解决方案11】:

                  你好,请注意像真正的工作。

                  孩子不能有两个妈妈

                  所以在java中,子类不能有两个父类。

                  【讨论】:

                  • “哈哈!”在哪里?按钮?
                  • Java 不是唯一具有继承性的编程语言。如果你只考虑父子关系,你就限制了你对继承的理解。行为(实际上是多重的)可以添加到一个类中,并且不需要存在具有所有这些特征的父类。
                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2013-06-18
                  • 1970-01-01
                  • 2013-10-30
                  • 1970-01-01
                  相关资源
                  最近更新 更多