所以,如果我用Java编写以下代码:
public class A extends A{
public static void main(String[] args){
}
}
这给出了涉及A。
的编译器错误消息循环继承如果我写两个A和B类,A继承B,B继承A。
,也会发生同样的情况这对我来说很有意义,因为很难想象无论如何这都是可能的。
然后我从我的大学的一位教授那里询问了这件事。他说有些语言是可能的,他感叹遗憾的是这在Java中是不可能的,并且他做过一些他曾经使用过循环继承的项目,但是我真的不能理解它。他还提到他曾经有过他希望使用循环继承的问题。
你能教育我这种奇怪的循环继承现象的可能用途吗?什么时候可能,怎么样?是否存在可能有用的问题?
答案 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中是不可能的。