3

如果a类扩展了b类,而b类扩展了c类,那么a是否继承自cb?如果是这样,在两者之间发生冲突的情况下,是否存在错误或者是否会覆盖另一个错误(如果是,是哪一个)?

如果标题不合适,请重命名问题。

编辑:我所说的冲突是这样的:

class c {
   int foo;
   //Stuff
}
class b extends c {
   String foo;
   //Stuff
}
class a extends b {
   //Stuff
}

a.foo字符串还是整数?

另一个编辑:所以据我所知,这里的继承有点像 CSS - 规则设置得越接近,它的优先级就越高(例如内联样式覆盖样式表)。这是考虑这个问题的好方法,还是有很大不同?

4

6 回答 6

5

如果两者中都存在某些东西bc则将a继承b使用的任何一个。

于 2012-06-24T13:50:34.363 回答
4

是的,a 继承自 b 和 c。我看不出在这种情况下怎么会发生冲突,因为 b 的方法覆盖对 a 有效。您可能会想到来自多重继承冲突的钻石问题,但那是当您有两个不同的父母,而不是两个父母,一个父母是另一个父母的时候。

您可能会遇到接口的“软”菱形问题,其中两个方法具有相同的签名,但一个方法的规则与另一个方法的规则不匹配。由于两个接口都没有实现它们的方法,所以不存在编译问题(据我所知),只是一个逻辑问题。

编辑 啊,我已经看到您对variables的编辑,我同意 Jimpanzee 对此的回应。这当然很容易测试:

public class Test3 {
   public static void main(String[] args) {
      MyA myA = new MyA();
      System.out.println("foo := " + myA.foo);
   }
}

class MyC {
   public int foo = 3;
   //Stuff
}
class MyB extends MyC {
   public String foo = "foo";
   //Stuff
}

class MyA extends MyB {

}
于 2012-06-24T13:46:16.000 回答
2

这个答案有一个更好的例子,并指出做这种事情被认为是不好的做法。(例如,Eclipse 会给你一个警告。)稍微扩展你的代码:

class c {
   int foo = 42;
   //Stuff
}
class b extends c {
   String foo = "foostr";
   //Stuff
}
class a extends b {
   //Stuff
}
class Main{
   public static void main(String[] args){
      a mya = new a();
      System.out.println(mya.foo);
   }
}

运行java Main打印foostr

于 2012-06-24T13:58:30.490 回答
2

嗯,规则如下。

  1. 任何子类都将继承最接近其层次结构。所以a将从b得到一切。因为继承堆栈上的所有内容在b之前都可用。因为b已经从其继承层次结构中继承了所有内容。

  2. 其次,如果b覆盖任何东西(实例变量/方法),那么a将看到覆盖的版本。因此,在您的情况下, a将获得 String foo。

于 2012-06-24T14:04:03.693 回答
2

在 Java 中,只有方法会被覆盖。其他一切都只是继承,只有命名空间冲突的问题,但一切仍然可以访问。在您的示例中,两个foos 都可以访问A(我已经更正了类名以使它们符合强 Java 命名约定):

class C {
  int foo;
  //Stuff
}
class B extends C {
  String foo;
  //Stuff
}
class A extends B {
  String x = ((B)this).foo;
  int i = ((C)this).foo;
}
于 2012-06-24T14:21:53.450 回答
1

是的,它继承自 c 和 b。为了防止/避免冲突,Java 支持单一层次模型(不同于其他 OOP 语言,如允许多类继承模型的 C++)。

于 2012-06-24T13:46:36.907 回答