繁体   English   中英

当两个类相互子类化时,为什么intelliJ会冻结?

[英]Why does intelliJ freeze when two classes subclasses each other?

我想知道如果两个类彼此子类化将会发生什么,并且我使用IntelliJ IDEA使用Scala尝试了它。 实现没有错误,但是当我在test对象内部取消注释时,IDE就会冻结,而我无能为力。 这里到底发生了什么?

class Shoe extends Table {

}

class Table extends Shoe {

}

object test {
    // val shoe = new Shoe()
}

看起来您的IDE版本正在尝试解析代码的类结构以及早识别错误和/或提供范围内的自动完成建议。 但它似乎没有条件停止跟踪/识别递归子类。

确保更新到最新版本,如果不能解决此问题,请提交错误报告。 在此之前,可能有一个设置可以在IDE中禁用,因此它不会冻结尝试解决循环类依赖关系。 更改自动完成设置时,更正和建议可能会失去一些准确性或完全禁用,但它将允许您运行/编译代码以识别错误(循环类依赖关系)并修复它。


循环类依赖是指多个类在循环中从彼此继承。 例如,如果我们有两个类, class Aclass B ,我们可以创建一个循环依赖循环,如下面的伪代码所示:

class A inherits B;
class B inherits A;

当许多编译器或解释器对此进行评估时,他们会看到第一行并尝试加载B 为了加载B ,他们转到第2行的声明。然后他们看到A需要加载。 在这里,智能编译器或解释器将翻转表,因为它已经知道它已经尝试并且无法加载A 一个天真的人会很乐意遵循指示。

load B!
load A!
load B!
load A!
load B!
load A!

最聪明的编译器和解释器实际上可以加载循环类依赖项并创建有效的代码。 但这些非常罕见。 作为程序员,有时在没有这种能力的语言中拥有循环类依赖是绝对必要的。

这就是类组合的概念所在。除了继承超类之外,您还可以以变量的形式将B的工作副本提供给A类。

在某些情况下,另一个很好的选择是提供转换功能,允许B成为A类; 如果它们都是从彼此继承的话,尽管它们的行为不同,它们很可能包含相同的数据! 某些语言具有执行此转换的内置功能。 最简单的例子是'类型转换'。 有些语言也将这种转换概括为参数多态,在这种情况下,您可以编写一个可以在任何兼容类型上运行的函数,而无需先进行转换。


引入一个难以解析的代码总是一种很好的方法来捕获编译器和解释器中的错误。 因此,当您必须编写并测试一个时,请记住这个片段!

在某些语言中,这样的东西,而不是一个bug,被认为是未定义的行为。 您不希望在您依赖的任何代码中弄乱未定义的行为。

没什么,编译器拒绝这段代码:

scala> :paste
// Entering paste mode (ctrl-D to finish)

class Shoe extends Table {}
class Table extends Shoe {}

// Exiting paste mode, now interpreting.

<pastie>:15: error: illegal cyclic reference involving class Shoe
       class Table extends Shoe {
                   ^

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM