談談接口和抽象類有什麼區別?

《Java核心技術面試精講–楊曉峯》學習筆記目錄

接口和抽象類的區別

接口

  • 接口是對行爲的抽象,它是抽象方法的集合,利用接口可以達到API定義和實現分離的目的。
  • 有一類沒有任何方法的接口用作標誌,比如Serializable接口就表示這個類可以被序列化
  • 不能實例化;
  • 不能包含任何非常量成員,任何field都是隱含着public static final的意義;
  • 沒有非靜態方法實現,也就是說要麼是抽象方法,要麼是靜態方法。
  • Java類實現interface使用implements關鍵詞
  • Java 8 以後增加了默認方法。在方法簽名前加上default。它可以爲接口添加新的方法,而不會破壞已有的接口的實現。
  • Java 8 新增了函數式接口,接口內只含有一個抽象方法。通常使用@FunctionalInterface AnnotationLambda表達式只能用於函數式接口

抽象類

  • 抽象類是不能實例化的類,用 abstract 關鍵字修飾 class
  • 其目的主要是代碼重用。除了不能實例化,形式上和一般的 Java 類並沒有太大區別,可以有一個或者多個抽象方法,也可以沒有抽象方法。
  • 抽象類大多用於抽取相關 Java 類的共用方法實現或者是共同成員變量,然後通過繼承的方式達到代碼複用的目的。
  • 繼承 abstract class 則是使用 extends 關鍵詞

面向對象基礎

基本要素

最後一個示例實在讓我有些驚訝,從沒注意過這些東西,就將他們全部複製下來了

OOP 原則在面試題目中的分析

我在以往面試中發現,即使是有多年編程經驗的工程師,也還沒有真正掌握面向對象設計的基本的原則,如開關原則(Open-Close)。看看下面這段代碼,改編自朋友圈盛傳的某偉大公司產品代碼,你覺得可以利用面向對象設計原則如何改進?


public class VIPCenter {
  void serviceVIP(T extend User user>) {
     if (user instanceof SlumDogVIP) {
        // 窮X VIP,活動搶的那種
        // do somthing
      } else if(user instanceof RealVIP) {
        // do somthing
      }
      // ...
  }

這段代碼的一個問題是,業務邏輯集中在一起,當出現新的用戶類型時,比如,大數據發現了我們是肥羊,需要去收穫一下, 這就需要直接去修改服務方法代碼實現,這可能會意外影響不相關的某個用戶類型邏輯。利用開關原則,我們可以嘗試改造爲下面的代碼:


public class VIPCenter {
   private Map<User.TYPE, ServiceProvider> providers;
   void serviceVIP(T extend User user) {
      providers.get(user.getType()).service(user);
   }
 }
 interface ServiceProvider{
   void service(T extend User user) ;
 }
 class SlumDogVIPServiceProvider implements ServiceProvider{
   void service(T extend User user){
     // do somthing
   }
 }
 class RealVIPServiceProvider implements ServiceProvider{
   void service(T extend User user) {
     // do something
   }
 } 

上面的示例,將不同對象分類的服務方法進行抽象,把業務邏輯的緊耦合關係拆開,實現代碼的隔離保證了方便的擴展。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章