abstract class 抽象類與interface 接口的區別,以及應用

抽象類


特點

  • 擁有抽象方法的類必須是抽象類
  • 抽象類可以沒有抽象方法
  • 繼承了抽象類的子類必須實現抽象方法,如果不實現抽象方法那麼子類必須是抽象類
  • 抽象類中可以對方法進行聲明也可以對方法進行實現
  • 抽象方法不能聲明爲static
  • 抽象方法不能聲明爲private
  • 抽象類不能聲明爲static
  • 抽象類可以implements接口,抽象類可以不用實現接口的方法,抽象類的子類需要實現抽象類implements的接口的方法

使用場景

JAVA爲一門單繼承語言,但是需要實現其多態性,所以我們對繼承需要謹慎處理。抽象類可以說是一個類的所屬,也就是說抽象類需要抽象出子類們所共同的屬性和方法。舉例如下:

public abstract class Person {
    abstract void sex();
}

public class Man extends Person {
    @Override
    void sex() {

    }
}

public class Woman extends Person {
    @Override
    void sex() {

    }
}

由上面可見,人是一個抽象類,男人和女人類繼承於人這個抽象類。該抽象類抽象出了,男人,女人都是人這個屬性,以及他們的屬性——性別。性別不同,所以必須實現性別這個方法。

又或者類似於廣播模式。

//觀察者
public abstract class Observer{
    protected Subject subject;
    public abstract void update();
}

//被觀察對象
public class Subject {

    //觀察者列表
    private List<Observer> observers = new ArrayList<>();
    private int state;

    public int getState() {
        return state;
    }

    //更改屬性state
    public void setState(int state) {
        this.state = state;
        notifyAllObservers();
    }

    //添加一個觀察者進入觀察者列表
    public void attach(Observer observer) {
        observers.add(observer);
    }

    //通知觀察者列表中的所有觀察者更新
    public void notifyAllObservers(){
        for (Observer observer : observers) {
            observer.update();
        }
    }
}

//其中一個觀察者
public class OctalObserver extends Observer {

    public OctalObserver(Subject subject){
        this.subject = subject;
        this.subject.attach(this);
    }

    @Override
    public void update() {
        System.out.println( "Octal String: "
                + Integer.toOctalString( subject.getState() ) );
    }
}

//其中一個觀察者
public class HexaObserver extends Observer {

    public HexaObserver(Subject subject){
        this.subject = subject;
        this.subject.attach(this);
    }

    @Override
    public void update() {
        System.out.println( "Hex String: "
                + Integer.toHexString( subject.getState() ).toUpperCase() );
    }

}

//其中一個觀察者
public class BinaryObserver extends Observer {

    public BinaryObserver(Subject subject){
        this.subject = subject;
        this.subject.attach(this);
    }

    @Override
    public void update() {
        System.out.println( "Binary String: "
                + Integer.toBinaryString( subject.getState() ) );
    }

}

從上述可以看出,後續的OctalObserver,HexaObserver,BinaryObserver都是觀察者,都繼承於Observer。這是因爲他們的根源都是觀察者,只不過他們類型不同。

所以抽象類可以說是定義了子類的根源,它的作用也是如此。


接口


特點

  • 接口只能對方法進行聲明,不能擁有方法體。(即實現方法)
  • 接口中的所有屬性默認爲public
  • 接口可以extends多個接口。繼承這些接口後可以不實現其方法,留給implements該接口的類來實現
  • 子類必須實現接口中的所有方法

使用場景

接口更傾向於描述一系列的行爲動作。比如,描述一個人的必須的活動,吃飯,睡覺,社交等。

public interface HowPersonDo {
     void sleep();
     void eat();
     void makeFriend();
}

兩者區別

在此之前可以先去了解下JAVA中的多態是什麼

  • 實現接口使用implements,繼承抽象類使用extends
  • 接口裏面只能對方法進行聲明,抽象類既可以對方法進行聲明也可以對方法進行實現
  • 接口中的方法必須全部實現,不然子類就必須爲抽象類。繼承抽象類,必須實現抽象類中的所有抽象方法,不然子類就必須爲抽象類。
  • 接口中的方法只能聲明,不能實現。而抽象類中的可以聲明也可以實現,實現的方法不是抽象方法。
  • 抽象類中可以沒有抽象方法
  • 擁有抽象方法的必須爲抽象類
  • 由於抽象類中方法必須全部實現,所以抽象方法不能爲static,也不能爲private
  • 接口可以繼承多個接口,類只能繼承一個類

使用區別:

  • 抽象類是抽象出一個事物的類別,接口是抽象出方法和功能。
  • 着重事物本質就用抽象類,關注操作就用接口。
  • 接口更具有擴展性。(因爲單繼承,多接口原因)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章