簡體   English   中英

為什么要創建抽象類和接口?

[英]Why make Abstract classes and Interfaces?

好吧,我打算問一下有什么區別,但之前已經回答了。 但現在我問他們為什么會產生這些差異呢? (我在這里講的是java,我不知道是否同樣適用於其他語言)

這兩件事看起來非常相似。 抽象類可以定義方法體,而接口則不能,但可以繼承多個接口。 那么他們為什么不(他們'我們的意思是Sun,當他們編寫Java時)做了一件事情,你可以編寫一個方法體這種類型可以被一個類繼承多次。

沒有能夠編寫方法體,或者延伸多次,我沒有看到它有什么優勢嗎?

因為允許類繼承同一方法簽名的多個實現會導致一個明顯的問題,即應該在運行時使用哪個。

Java通過僅支持接口的多重繼承來避免這種情況。 每個接口中聲明的簽名可以更容易組合(Java基本上使用所有方法的並集)

C ++中的多重繼承會導致語義模糊,如鑽石繼承問題 MI非常強大,但后果復雜。

使接口成為一種特殊情況也提高了概念作為信息隱藏手段和降低程序復雜性的可見性。 在C ++中,定義純抽象基礎是成熟程序員的標志。 在Java中,您會在程序員發展的早期階段遇到它們。

多重繼承在一種語言(真正的編譯器)中更難實現,因為它可能導致某些問題。 這里已經討論過這些問題: 多重繼承的確切問題是什么

我一直認為這是Java的妥協。 接口允許類完成多個合同而不必擔心多重繼承。

考慮這個例子:

public abstract class Engine
{
  public abstract void switchPowerOn();
  public abstract void sprinkleSomeFuel();
  public abstract void ignite();

  public final void start()
  {
    switchPowerOn();
    sprinkleSomeFuel();
    ignite();
  }
}

抽象類可以幫助您擁有可以或不可以覆蓋的可靠基礎方法,但在這些方法中,它使用抽象方法為您提供執行特定事物的機會。 在我的示例中,不同的發動機具有不同的實施方式,即它們如何接通電源,為點火噴灑一些燃料,以及進行點火,但是發動機的起動順序始終保持不變。

這種模式被稱為“表單模板方法”,坦率地說,對我來說,Java中抽象類的唯一明智用法。

讓它們成為一件事就是Scala人用Traits采用的路徑,這是一個可以擁有方法並支持多重繼承的接口。

對於我來說,我認為接口是干凈的,因為它們只指定需求(按合同設計)而抽象類定義了常見的行為(實現),因此不同的工具用於不同的工作? 接口可能允許在編譯期間更有效地生成代碼?

您描述的另一種方法是C ++使用的方法(例如mixins)。 與這種“多重繼承”相關的問題相當復雜,並且在C ++中有一些批評者。

繼承意味着您繼承父類的性質 (含義)和責任 (行為),而接口實現意味着您履行合同(例如Serializable),這可能與類的核心性質或責任無關。

抽象類允許您定義您想要通用而不是直接可實現的性質,因為它必須是專用的。 您知道如何執行某些高級任務(例如,根據某些參數做出決策),但您不知道某些較低級別操作的詳細信息(例如,計算某些中間參數),因為它取決於實現選擇。 解決此問題的另一種方法是策略設計模式 它更靈活,允許運行時策略切換和Null行為,但它更復雜(並不總是需要運行時切換)。 此外,您可能會失去一些含義和輸入設施(多態和類型檢查變得有點困難,因為策略是一個組件,而不是對象本身)。

抽象類= is-a,策略= has-a

編輯:至於多重繼承,請參閱Pontus Gagge的答案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM