【问题标题】:Is this Multiple inheritance in java?Why not Java supports extends ChildOne,ChildTwo syntax?这是java中的多重继承吗?为什么Java不支持extend ChildOne,ChildTwo语法?
【发布时间】:2015-07-10 19:45:28
【问题描述】:

我有三门课

ChildTwo

public class ChildTwo {
    public void methodOfChildTwo() {
        System.out.println("methodOfChildTwo.");
    }
}

ChildOne 扩展了 ChildTwo

public class ChildOne extends ChildTwo{
    public void methodOfChildOne() {
        System.out.println("methodOfChildOne.");
    }
}

扩展 ChildOne 的父级

public class Parent extends ChildOne{
    public void methodOfParent() {
        System.out.println("methodOfParent.");
    }
}

当我创建 Parent 的对象时,我可以调用所有三个方法,因为所有这些方法都是在 Parent 类中继承的。

Parent parent =new Parent();
parent.methodOfParent();
parent.methodOfChildOne();
parent.methodOfChildTwo();

我的问题是

  1. 我能说这样我可以在Java中实现多重继承吗?
  2. 这种方法在概念上与多个扩展类似,例如 Parent extends ChildOne,ChildTwo(Java 不支持这些语法)。为什么 Java 不支持这种语法,尽管我们可以通过上述方式实现这一点?

请有人澄清一下。

【问题讨论】:

  • 多重继承将使Child 扩展Father 和Mother。您将如何实现这一目标?
  • 多重继承类似于.<:;您在这里拥有的是.-.-.。点代表类,< 和 - 代表继承。如果你想要一个非常粗略的文字解释。
  • 不支持,因为如果 ChildOne 和 ChildTwo 都有相同的方法,它如何确定保留哪个方法,忽略哪个方法。这可能看起来很容易,但有些人可能会认为它在一种方式上比另一种方式更有意义。通过保持简单并只允许单一继承,事情变得更简单
  • 在概念上类似于(祖母、母亲、女儿)和(母亲、父亲、女儿)。
  • 我的父类扩展了两个类

标签: java


【解决方案1】:

首先Java不支持多重继承,因为它可能会导致歧义。 (注意:像 C++ 这样的语言确实支持多重继承)。

1.我能说这样我可以在Java中实现多重继承吗?

这仍然不是多重继承。

见下图:

您给定的代码就像右侧的图表。多重继承将直接从其所有父级继承所有属性和行为(Java 中不支持)。

2. 这种方法在概念上与多个扩展类似,例如 Parent 扩展 ChildOne,ChildTwo(Java 不支持这些语法)。

您的方法实际上与多个扩展在概念上并不相似。 Java 不支持这一点以防止歧义。想象一下,两个父类都有一个类似签名的方法。

class Bomb{
    public void activate();
}

class LightBulb{
    public void activate();
}

class Child extends Bomb, LightBulb{  //Imagine if this is allowed
    //When I call activate(), will it activate the bomb or the lightBulb?
}

为什么Java不支持这种语法,虽然我们可以通过上面提到的方式实现这一点?

这两种情况不同,不能通过a extends b、b extends c实现多重继承。从概念上讲,它是不同的,因为层次结构完全不同。

在多重继承中,你想要扩展的两个父类可以完全不相关。想象一下Pegasus extends FlyingCreature, Horse。

Pegasus 是一个FlyingCreature,它是也是一个Horse,但是FlyingCreature和Horse是不相关的强烈> 完全没有。

在您给定的示例中,所有后续扩展父类都是另一个的子集。它们都是相关的。

Mammal 是 Animal和Lion 是 Mammal和是也是Animal.


如果您说您提到的方法在概念上类似于多重继承,请考虑以下场景:

您的任务是从class FlyingCreature 和class Horse 创建class Pegasus。

你打算这样做吗?

class FlyingCreature{
}

class Horse extends FlyingCreature{   //But Horses do not fly!
}

class Pegasus extends Horse{  //You got what you want here, but the Horse class is wrong.
}

还是这个?

class Horse{
}

class FlyingCreature extends Horse{   //All flying creatures are horses? Are you sure?
}

//You got what you want here, but the FlyingCreature class is wrong.
class Pegasus extends FlyingCreature {
}

所以现在你看,它不能完成,因为两个父类根本不相关。为了在一定程度上实现所谓的“多重继承”,Java 使用interface。

【讨论】:

    【解决方案2】:

    看到这个帖子关于同样的问题:Why is Multiple Inheritance not allowed in Java or C#?

    最好的答案是太麻烦了,收益太少了。你可以用接口做同样的事情。

    你可以实现多个接口,所以不需要多重继承。

    【讨论】:

      【解决方案3】:

      Dog 既是 Mammal 又是 Pet。然而Pet 不是Mammal。您不能仅使用 Java 类对 Mammal、Pet 和 Dog 之间的关系进行建模。这是因为 Java 不支持多重继承。

      上面不在概念上类似于Animal、Mammal和Dog之间的关系,这是Java支持的。这就是为什么你的问题的“虽然”部分是不合理的。

      【讨论】:

        【解决方案4】:

        不,它在概念上并不相似。

        虽然Parent 扩展了ChildOne,而ChildOne 又扩展了ChildTwo 并继承了两者的方法,但它会导致以下问题:

        ChildOne[] arr = new ChildOne[2];
        arr[0] = new ChildOne();
        arr[1] = new ChildTwo(); // <--- this should have failed
        

        假设ChildOne 和ChildTwo 应该是互斥的,那么最后的分配arr[1] = c2 应该会因为ArrayStoreException 而失败。

        【讨论】:

          【解决方案5】:

          你解释的是“多级继承”。

          多级继承 -> B 扩展 A。C 扩展 B。 多重继承 -> P 扩展 Q、R。这在 java 中是不允许的。对于多重继承,我们使用接口。作为一个类可以实现任意数量的接口。

          【讨论】:

            【解决方案6】:

            您的示例是多级继承,而不是多重继承。

            把继承想象成有父母。你继承了你父母的财产,反过来又继承了他们从祖父母那里得到的东西。你不会称之为多重继承吧?

            多类继承就像从你的父母那里获取基因,然后从其他父母那里(来自不同的家谱)。在现实生活中没有意义,因为如果你有重复的基因怎么办?如果你从一组父母那里获得蓝眼基因,从另一组父母那里获得绿眼基因,你会选择哪一个?

            在 Java 中也是一样的:

            这是一个简单的例子:

            public class A {
                public void doSomething() {
                    // Does something
                }
            }
            
            public class B {
                public void doSomething() {
                    // Does something else
                }
            }
            
            public class C extends A,B {
                ....
            }
            
            public static void main(String[] args) {
                C newC = new C();
                newC.doSomething();
                // PROBLEM!
            }
            

            应该选择哪个doSomething()?没有办法说!所以 Java 通过不允许多个超类避免了这个问题(我敢肯定还有很多其他问题)。

            【讨论】:

              猜你喜欢
              • 2011-04-15
              • 1970-01-01
              • 2016-04-18
              • 2014-03-04
              • 1970-01-01
              • 1970-01-01
              • 2015-11-11
              • 1970-01-01
              • 2020-05-20
              相关资源
              最近更新 更多