oop - 介面VS 抽象類Class ( 常規OO )

  显示原文与译文双语对照的内容

最近我有兩個電話面試,我被問及一個介面和一個抽象類之間的區別。 我已經解釋了我可以想到的每個方面,但似乎他們在等我提及一些特定的東西,我不知道它是什麼。

從我的經驗來看,我認為如下。 如果我缺少一個要點,請告訴我。

磅:

介面中聲明的每個方法都必須在子類中實現。 介面中只能存在事件,委託,屬性( C# ) 和方法。 一個類可以實現多個介面。

抽象類:

只有抽象方法必須由子類實現。 抽象類可以有帶有實現的普通方法。 抽象類也可以在事件,委託,屬性和方法旁邊有類變數。 一個類只能實現一個抽象類,因為non-existence中的Multi-inheritance是。

  1. 在這之後,面試官提出了一個問題"如果你有一個抽象的類,並且只有抽象方法? 這與介面有什麼不同"我不知道答案,但我認為它是上面提到的繼承?

  2. 另一位面試官問我,如果介面中有一個公共變數,這與抽象類有什麼不同? 我堅持你不能在介面內有公共變數。 我不知道他想要聽到什麼,但他還是不滿意。

另請參閱:

时间:

雖然你的問題表明它是針對"通用 oo"的,但它似乎關注于. NET 使用這些術語。

在. NET ( 類似於 Java ) 中:

  • 介面沒有狀態或者實現
  • 實現介面的類必須提供該介面的所有方法的實現
  • 抽象類可能包含狀態( 數據成員) 和/或者實現( 方法)
  • 抽象類可以繼承而不實現抽象方法( 儘管這樣一個派生類是抽象的)
  • 介面可以是 multiple-inherited,抽象類不能是( 這可能是關鍵的具體理由來介面獨立於abtract可以存在類- 它們允許多重繼承,它移除的實現帶來的許多問題提出了通用mis系統) 。

作為一般的OO術語,差異不一定是明確的。 例如有 C++ 程序員可能擁有類似的嚴格定義( 介面是抽象類的嚴格子集,不能包含實現),而有些可能認為具有一些默認實現的抽象類仍然是介面或者non-abstract類仍然可以定義介面。

事實上,有一個 C++ 成語叫做所在的Non-Virtual介面( NVI ) Non-Virtual種方法都是公共方法'thunk'私有虛更新法。

類比:當我在空軍中時,我參加了飛行員訓練,成為了 USAF ( 美國空軍) 飛行員。 那時我沒有資格飛行,而且不得不參加飛機類型訓練。 我合格后,我是一個飛行員( 抽象類) 和一個C-141飛行員( 具體類別) 。 在我的一個工作分配中,我得到了額外的職責: 安全官員。現在我仍然是一名飛行員和一個C-141飛行員,但我也執行了安全官員的職責。 飛行員不是一個安全人員,其他人也可以這樣做。

所有的USAF飛行員都必須遵守某些空中Force-wide規則,以及所有 C-141 ( 或者 F-16,或者 T-38 ) 飛行員'是'USAF飛行員。 任何人都可以成為安全人員。 因此,總結:

  • Pilot: 抽象類
  • C-141 Pilot: 具體類
  • ISafety官員:介面

添加的注意:這是為了幫助解釋概念,而不是一個編碼建議。 查看下面的各種評論,討論很有趣。

我認為他們尋找的答案是基本的或者哲學上的差異。

當派生類共享抽象類的核心屬性和行為時使用抽象類繼承。 實際定義類的行為類型。

另一方面,介面繼承是在類共享外部行為時使用的,這些行為不一定定義派生類。

為eg。一輛汽車和一輛卡車分享大量的核心屬性和行為的一種汽車的抽象類,但他們也分享一些外圍的行為像生成哪些甚至非汽車類喜歡Drillers或者PowerGenerators共享和不一定定義一輛汽車或卡車,這樣汽車、卡車、司鑽和PowerGenerator都可以分享相同的介面IExhaust的排氣。

短:抽象的類,用來造型( 例如動物的類似的期待類層次結構的類可以是抽象類,該類人。Lion,虎可以具體派生類)

介面是為通信 2相似/非相似的類之間的類實現介面,它不關心自己的類型( 例如 高度可以是介面屬性,可以由人,建築,樹實現。 不管你是否可以吃,你可以游泳,你可以死或者任何東西。 它只需要一個你需要高度( 在你的類中實現)的東西。

還有一些不同之處-

介面不能有任何具體實現。 抽象基類。這允許你在那裡提供具體的實現。 這可以讓抽象基類真正提供一個更嚴格的契約,wheras介面實際上只是描述如何使用一個類。 ( 抽象基類可以有定義行為的non-virtual成員,從而給基類作者提供更多的控制。)

一個類可以實現多個介面。 類只能從單個抽象基類派生。 這允許使用介面的多態層次結構,但不支持抽象基類。 這也允許pseudo-multi-inheritance使用介面。

抽象基類可以在v2+中修改而不破壞 API 。 對介面的更改正在破壞更改。

抽象基類不同,[C#/.NET Specific]介面可以應用於值類型( 結構體) 。 結構不能從抽象基類繼承。 這允許在值類型上應用行為契約/用法準則。

繼承
考慮一輛汽車和一個公共汽車。 他們是兩個不同的車輛。 但是他們仍然分享一些共同的特性,比如方向盤,剎車,齒輪,引擎等。
因此,繼承概念可以表示如下。


public class Vehicle {
 public Driver driver;
 public Seat[] seatArray;//In java and most of the Object Oriented Programming(OOP) languages, square brackets are used to denote arrays(Collections).
//You can define as many properties as you want here..
}

現在是自行車。


public class Bicycle extends Vehicle {
//You define properties which are unique to bicycles here..
 public Pedal pedal;
}

還有汽車。


public class Car extends Vehicle {
 public Engine engine;
 public Door[] doors;
}

這些都是關於繼承的。 我們使用它們將對象分類為簡單的基本形式和他們的孩子。

抽象類

抽象類是不完整的對象。 為了進一步理解它,我們再次考慮汽車模擬。
汽車可以被驅動。 對但是不同的車輛是以不同的方式驅動的。 例如你不能像駕駛自行車一樣駕駛汽車。
如何表示車輛的驅動功能? 很難檢查它是什麼類型的車輛,並使用它自己的功能驅動它;在添加新類型的車輛時,你必須反覆更改驅動程序類。
下面是抽象類和方法的角色。 你可以將驅動器方法定義為抽象,以表明每個繼承的子級必須實現這裡函數。
所以如果你修改了vehicle類。


//......Code of Vehicle Class
abstract public void Drive();
//.....Code continues

自行車和汽車還必須指定如何駕駛它。 否則代碼將無法編譯,並引發錯誤。
簡而言之,抽象類是部分不完整的類,具有一些不完整的函數,繼承子類必須指定它們自己的。

介面介面完全不完整。 它們沒有任何屬性。 它們只是表明繼承子對象可以做一些事情。
假設你有不同類型的行動電話。 每一個都有不同的方法來完成不同的功能;例如: 打電話給某人。電話製造商指定如何做。 在這裡,行動電話可以撥一個號碼,也就是說,它是 dial-able 。 我們將它的表示為一個介面。


public interface Dialable {
 public void Dial(Number n);
}

在這裡,Dialable的製造商定義如何撥打一個號碼。 你只需要給它一個號碼來撥號。


Dialable myPhone1 = new Dialable() {
 public void Dial(Number n) {
//Do the phone1's own way to dial a number
 }
}

Dialable myPhone2 = new Dialable() {
 public void Dial(Number n) {
//Do the phone2's own way to dial a number
 }
}

這裡使用介面而不是抽象類,你不必擔心它是屬性。 Ex: 它有touch-screen或者撥號盤,是固定固定電話還是行動電話。 你只需要知道它是否是撥號的;它是 inherit(or implement)的介面。
開發人員通常使用介面來確保對象之間的interoperability(use interchangeably),只要它們共享一個公共函數( 就像你需要撥打一個電話或者行動電話一樣,你只需要撥打一個號碼) 。 簡而言之,介面是抽象類的簡單版本,沒有任何屬性。
另請注意,你可能 implement(inherit) 任意數量的介面為你想要的,但你可以只 extend(inherit) 一個父類。

;更多信息抽象類 vs 介面

面試官正在 barking 。 對於 C# 和Java這樣的語言,有不同的地方,但在其他語言中,比如 C++ 。 OO理論並不區分兩者,只是語言的語法。

抽象類是一個具有實現和介面( 純虛方法)的類,它將被繼承。 介面通常沒有任何實現,但只有純虛函數。

在 C# 或者Java中,沒有任何實現的抽象類與介面中的介面和只能從其中繼承的事實的介面不同。

通過實現介面,你實現了組合("has-a"關係) 而不是繼承("is-a"關係) 。 這是一個重要的原則,當你需要使用介面來實現一個行為的組合而不是一個繼承的時候。

用於. Net.

第二個面試官的回答也是第一個面試的答案。 抽象類可以具有實現,並且狀態不能有介面。。

編輯:在另一個注意中,我甚至不會使用'子類'( 或者'繼承'短語) 來描述'定義為實現'介面的類。 對於我來說,介面是一個類的定義,如果它已經被定義為'實現'介面,那麼該類必須遵守。 它不繼承任何東西。。 你必須自己添加所有東西。

從概念上講,保持語言特定的實現,規則,好處和實現任何編程目標都可以使用 code/data/property, blah單個或者多個繼承,單個繼承或者多個繼承

1-抽象( 或者純抽象) 類是實現層次結構的一種方法。 如果你的業務對象看起來有些相似,那麼表示一個父級的子( 層次結構) 類型只有繼承/抽象類才會被使用。 如果你的業務模型沒有層次結構,那麼繼承不應該被使用( 這裡我討論的不是編程邏輯 比如 一些設計模式需要繼承) 。 從概念上講,抽象類是實現面向對象的業務模型的一種方法,它與介面無關,實際上與介面無關,因為在實現時使用了抽象類,程序員通常強調編程,而程序員通常強調編碼。 [Keep this in mind as well that Abstraction is different than Abstract Class] 。

2-介面是一個契約,它是由更多的函數之一表示的完整業務功能。 這就是為什麼它被實現而不是繼承。 業務對象( 層次結構的一部分) 可以有任意數量的完整業務功能。 它與抽象類無關,一般意味著繼承。 例如一個人跑,大象也可以運行了一個鳥兒可以運行等等,所有這些具有不同層次的對象將實現該介面或者吃或者朗讀介面運行。 不要進入實現,因為你可能實現它,因為它為實現這些介面的每個類型都有抽象類。 任何層次結構的對象都可以有一個 functionality(interface),它與它的層次結構無關。

我相信,介面還沒有誕生,以實現多重繼承或者曝光公共行為,和純抽象類不到超過規則介面與之類似,但界面是一個功能,一個對象可以完成核心的結構( property+functionality ) ( 通過該介面的功能) 和抽象類表示的父證書層次來產生子進程擁有父進程

在特定於語言的實現,除非有人要求explicitly,當你被要求區分,它實際上是概念上的區別而不是不同的區別

我相信,這兩個面試者也在等一行拉直前面這兩個,並在你失敗他們試圖把你拉向著這種差異通過實現一個像之間的另一個區別

如果具有抽象方法的抽象類是什麼?

...