簡體   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