循环继承使用

时间:2012-11-19 23:10:57

标签: java inheritance

所以,如果我用Java编写以下代码:

public class A extends A{
    public static void main(String[] args){
    }
}

这给出了涉及A。

的编译器错误消息循环继承

如果我写两个A和B类,A继承B,B继承A。

,也会发生同样的情况

这对我来说很有意义,因为很难想象无论如何这都是可能的。

然后我从我的大学的一位教授那里询问了这件事。他说有些语言是可能的,他感叹遗憾的是这在Java中是不可能的,并且他做过一些他曾经使用过循环继承的项目,但是我真的不能理解它。他还提到他曾经有过他希望使用循环继承的问题。

你能教育我这种奇怪的循环继承现象的可能用途吗?什么时候可能,怎么样?是否存在可能有用的问题?

5 个答案:

答案 0 :(得分:6)

我挖出了这个interesting reference:基本上它表示循环继承是有效的,只要没有重复的字段,因为任何字段的查找只需要遍历循环的一个循环以找出含义。如果一个字段重复,那么这两个定义中没有一个比另一个更有效,显然会出现问题。

因此,假设您要将某人定义为人类和选民,并为每个人设置不同的属性。在伪代码中:

class Person extends Human:
  String name;

class Human extends Voter:
  String language;

class Voter extends Person:
  Country residence;

现在,您可以在不必定义层次结构的情况下解决个人的不同方面,并且可以将不同的人实例化为Person(具有名称),Human(表示语言)或Voter(在特定国家/地区) 。没有哪个方面比另一方面更重要。

虽然有趣,但我认为在研究项目之外使用是不切实际的。想象一下,为所有将参数传递给super()构造函数的类都有构造函数 - 很容易弄乱整个构造。

更新:给定的伪代码在转换为Java 8时不会编译,并且显然在任何语言下(Cecil除外,如上面给出的链接所示)。似乎没有人发现任何有效用途,因此不允许循环继承。这并不意味着这个概念本来就不可能;只是实际用途并不能证明实施特殊情况的努力是正确的。

答案 1 :(得分:1)

我不同意接受的答案,声明他们的代码不会抛出错误。我正在运行Java 8并编译了以下代码:

class Person extends Human:
  String name;
class Human extends Voter:
  String language;
class Voter extends Person:
  String residence;

我收到一条错误声明"错误:涉及Person的循环继承。"

因此,在Java中,您不能拥有循环继承。

答案 2 :(得分:0)

我只能看到这些类处于同一级别的层次结构中。将类层次结构视为树,它就是这样。 Java查找层次结构至少高于或等于一个级别。在某些语言中,您可以从与您正在使用的类相同级别的类继承特性。

答案 3 :(得分:0)

我没有循环继承感。我不知道为什么你的教授认为在任何情况下,被称为 IS-A 关系的继承实体表明,如果B是A的子类,那么B IS-A A在某种意义上是有用的在任何地方都需要A然后可以毫无问题地使用B( Liskov替换原则)。

现在,理论上,如果A是B的子类,而B是A的子类,则两个类必须具有完全相同的外部接口。这是因为如果您向其中任何一个方法添加方法,另一个方法将自动继承相同的方法,因此您可以覆盖它以获得其他实现。

此外,您会遇到许多奇怪的副作用发生的情况(考虑调用A.foo()和调用super.foo() B.foo()的方法super.foo()。我不这样做看到任何实际的原因,因为这应该被允许。

继承旨在作为一个树,其中每个子类指定树中的行为或类,在同一级别具有两个类并不意味着任何有用的东西。

答案 4 :(得分:0)

循环继承是没有用的,而且让我们从逻辑上理解为什么不允许这样做。

我想从Object类开始,如果一个类没有扩展它扩展的任何类Object类(这是真的),并且如果一个类间接扩展任何其他类扩展Object类。

示例:

class B
{
..//
}
class A extends B
{
...//
}

A扩展Object,因为B类扩展了Object类。

因此,当我们执行循环继承时,它从不扩展Object类。

示例:

class A extends A
{
}

我希望我很清楚,所以还有一个不能扩展Object类的类,这在Java中是不可能的。