抽象類和介面區別

2021-09-30 12:31:26 字數 1501 閱讀 3330



在開發人員崗位面試時,是否了解抽象類和介面之間的基本區別是乙個很重要的考量因素。

完全不是。筆者面試過很多人,通常問的第乙個問題是關於介面和抽象類的區別。但實際上很少有程式設計師能給出正確的答案。

就這個問題來說,初級程式設計師可能都會清楚之間的區別,可能也並不一定理解其背後的原因,但其結構上的差異,特別是針對特定語言(幾乎和所有的物件導向的語言一樣)應該深入了解。

同時,筆者也發現其他職位候選人(有時甚至是高階職位)竟然也不知道這之間的差異,或者只知道的乙個或幾個。

如果只是需要了解這些內容那並不難,但這些都是物件導向的基礎知識,因此想要設計良好的**必須對其有乙個深入的認識。

下面將詳細介紹這些基礎知識。

下面將從眾所周知的介面和抽象類的區別開始。這種差異是關於繼承的,任何類都可以實現多個介面,但是只能擴充套件乙個類,也只能有乙個父類。

多個類擴充套件是乙個語言特性,它存在於一些物件導向的語言。為什麼呢?因為它帶來的問題往往多於價值。

當乙個類有許多父類時,有乙個情況就是完全相同的方法會宣告多個,因此必須顯式地「告知」究竟需要的是哪乙個。

這樣的**通常難以維護,因為對其進行的任何修改或者重構都必須小心地檢查。另一方面,如果乙個類需要擴充套件(至少)兩個擁有相同方法的類,那麼dry規則顯然會被破壞(因此需要從別處下手),或者說會干擾到single responsibility principle(sap)。

「如果多個類的繼承如此糟糕,為什麼它可以實現許多介面呢?」——如果這樣的問題在你的腦海盤旋,我不得不承認這是乙個絕妙的問題。

然而,答案很簡單。每乙個介面都是基於函式而不是乙個類去實現。所以,即使實現十個不同的介面,每個包含相同的方法宣告,內部也不會發生衝突。介面保證了方法的存在,而不是去說明方法的實現,這意味著,只要不違反srp,你完全可以實現多個介面。

介面中的所有方法都是public的,但對於抽象類的宣告並沒有這樣的規則,當然不能是private。為什麼不能private?因為乙個抽象方法需要在子類中實現,但private無法訪問子類,因此不抽象類不可能存在private屬性。

接著回歸主題。正如上文寫道的,介面是乙個函式的保證,你可以把它當作使用介面的類和實現這個介面的類之間的乙個合約——保證乙個特定類將實現所有宣告的方法。這也是為什麼這些方法必須是public的原因。因為被嚴格的限制到了實現上,所以其他一切都不成問題。

然而,當涉及到抽象類時並非這樣。我們總是可以有不同的類組,除了這幾方面基本上不同以外,其他地方幾乎一樣,類體的公共方法也是非常相似的。在這種情況下,可以建立protected方法來保持類之間的差異。template method就是乙個很典型的例子。

介面只能包含方法宣告,而抽象類還可以包含方法的定義。

介面的重點在於提供特定函式,而抽象類還在於子類實現的相似性,不僅僅是其中的函式。

介面和抽象類中都可以定義常量。這是因為這些值不依賴於特定物件,對它們來說都是相同的。

抽象類可以包含屬性,但介面卻不能。原因與宣告和定義是一樣的。

除了說明差異,筆者也試**釋它產生的原因。這不僅是因為人們發明某個語言時的突發奇想,而是源於語言背後所支撐的理念

抽象類和介面區別

含有abstract修飾符的class即為抽象類,abstract類不能建立的例項物件。含有abstract方法的類必須定義為abstract class,abstract class類中的方法不必是抽象的。abstract class類中定義抽象方法必須在具體 concrete 子類中實現,所以,...

抽象類與介面區別

抽象類 抽象類無法例項化 即不能new 使用抽象方法,該方法是只需宣告不需要實現。抽象方法需要定義在抽象類中,乙個類包含抽象方法,這個類一定是抽象類。如果某個類是抽象類,他可以有具體方法 有宣告,有實現 也可以有抽象方法。子類繼承父類 該父類為抽象類 就要實現該父類的所定義的所有抽象方法,否則該子類...

java中抽象類和介面區別

抽象類前使用abstract關鍵字修飾,則該類為抽象類 應用場景 在某些情況下,某個父類只是知道其子類應該包含怎樣的方法,但無法準確的知道這些子類如何實現這些方法。從多個具有相同特徵的類中抽象出乙個抽象類,以這個抽象類作為子類的模板,從而避免了子類設計的隨意性 作用 限制規定子類必須實現某些方法,但...