抽象類
特點
- 擁有抽象方法的類必須是抽象類
- 抽象類可以沒有抽象方法
- 繼承了抽象類的子類必須實現抽象方法,如果不實現抽象方法那麼子類必須是抽象類
- 抽象類中可以對方法進行聲明也可以對方法進行實現
- 抽象方法不能聲明爲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
- 接口可以繼承多個接口,類只能繼承一個類
使用區別:
- 抽象類是抽象出一個事物的類別,接口是抽象出方法和功能。
- 着重事物本質就用抽象類,關注操作就用接口。
- 接口更具有擴展性。(因爲單繼承,多接口原因)