java基礎(十二)抽象類(Abstract class)和介面(interface)
抽象類(Abstract class):
抽象類概述:
抽象類是對根源的抽象(即對本質的抽象與其他類的本質不同)。
抽象類表示的是這個東西是什麼。比如男人女人,,他們的抽象類就是人,所以繼承也只能繼承一個類(抽象類)(是人那就是人,不能是別的生物)
且如果有抽象的功能(吃,睡…),該類也必須是抽象類
抽象類的特點
- 抽象類和抽象方法都只能用abstract關鍵字修飾
- 抽象類中不一定只能有抽象方法,也可以沒有,但有抽象類的一定是抽象方法
- 不能例項化
- 抽象類中的構造方法用於子類訪問父類資料的初始化
- 抽象類的子類實現:
-
- 不重寫抽象方法,該類定義為抽象類
-
- 重寫所有的抽象方法 ,這時候子類就是一個具體的類
抽象類的成員特點(與介面區分)
- 成員變數 :可以是變數也可以是常量
- 構造方法:有
- 成員方法:有抽象方法也有非抽象方法
//父類
public abstract class Person {
private int a;
public Person(){
}
public abstract void show(); //抽象方法 沒有方法體
public void demo(){ //非抽象方法
}
}
public class Student extends Person {
//具體子類就必須重寫所有抽象方法
@Override
public void show() { //且變成非抽象方法
// TODO Auto-generated method stub
}
}
//抽象子類
public abstract class Teacher extends Person{
}
示例:
//父類
package com.st.basis.day09.abstarctdemo;
public abstract class Animal {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Animal(){ //無參構造
}
public Animal(String name, int age){ //帶參構造
this.age = age;
this.name = name;
}
public abstract void eat(); //抽象方法
}
//子類
package com.st.basis.day09.abstarctdemo;
public class Dog extends Animal {
public Dog(){
super();
}
public Dog(String name, int age) {
super(name,age); //呼叫父類的構造方法
}
@Override
public void eat() {
System.out.println("狗吃肉");
}
}
//測試類
package com.st.basis.day09.abstarctdemo;
public class AbstractDemo {
public static void main(String[] args) {
Animal dog1 = new Dog(); //多型建立物件dog1
dog1.eat();
dog1.setName("旺財");
dog1.setAge(1);
System.out.println(dog1.getName()+dog1.getAge());
System.out.println("--------");
Animal dog2 = new Dog("往往",10); //多型建立物件dog2
System.out.println(dog2.getName()+dog2.getAge());
}
}
介面(interface)
介面概述:
是對行為的抽象,裡面包含供別人呼叫的方法和函式
抽象類把男人,女人抽象為人,定義他們是什麼。而介面就定義他們做什麼。
介面是一種極度抽象的型別,它比抽象類更加“抽象”,並且一般情況下不在介面中定義變數。
介面特點
- 介面用關鍵字interface表示
interface 介面名(){}
- 類實現介面:
class 類名 implements 介面名(){}
- 介面不能例項化(利用多型)
實現介面:
- 抽象類實現介面:意義不大,Dog應該是一個具體類,變成抽象還得再繼承
public abstract class Dog implements Aniamal{
}
- 具體類實現介面:(很常見)
//介面
public interface Aniamal {
public abstract void eat();
}
//子類
public class Dog implements Aniamal{
@Override
public void eat() {
System.out.println("狗吃肉");
}
}
//測試
public class InterfaceDemo {
public static void main(String[] args) {
Aniamal dog2 = new Dog();
dog2.eat();
}
}
介面中的成員特點:
- 介面中的成員變數預設為:public static final 變數(且無法修改)
- 方法指定為***public abstract***(也無法修改)
- 介面沒有構造方法
- 方法則必須也只能是抽象方法
抽象類與介面區別:
- 成員變數區別具體看上面
- 關係區別:
類與類:繼承關係,只能單繼承,但可以多層繼承
//Dog是類
//Aniamal,Aniamal2都是類
class Dog extends Aniamal{} //正確
class Dog extends Aniamal,Aniamal2{} //不支援
類與介面:實現關係。可以單實現,也可以多實現
//Dog是類
//Aniamal,Aniamal2都是介面
class Dog implements Aniamal{} //正確
class Dog implements Aniamal,Aniamal2{} //支援
class Dog extends implements Aniamal,Aniamal2 //支援
介面與介面:繼承關係, 可以單繼承,也可以多繼承
//Dog,Aniamal,Aniamal2都是介面
interface Dog extends Aniamal{} //正確
interface Dog extends Aniamal,Aniamal2{} //支援
- 設計層面的區別:
1)抽象類是對一種事物的抽象,即對類抽象,而介面是對行為的抽象。抽象類是對整個類整體進行抽象,包括屬性、行為,但是介面卻是對類區域性(行為)進行抽象。舉個簡單的例子,飛機和鳥是不同類的事物,但是它們都有一個共性,就是都會飛。那麼在設計的時候,可以將飛機設計為一個類Airplane,將鳥設計為一個類Bird,但是不能將 飛行 這個特性也設計為類,因此它只是一個行為特性,並不是對一類事物的抽象描述。此時可以將 飛行 設計為一個介面Fly,包含方法fly( ),然後Airplane和Bird分別根據自己的需要實現Fly這個介面。然後至於有不同種類的飛機,比如戰鬥機、民用飛機等直接繼承Airplane即可,對於鳥也是類似的,不同種類的鳥直接繼承Bird類即可。從這裡可以看出,繼承是一個 "是不是"的關係,而 介面 實現則是 "有沒有"的關係。如果一個類繼承了某個抽象類,則子類必定是抽象類的種類,而介面實現則是有沒有、具備不具備的關係,比如鳥是否能飛(或者是否具備飛行這個特點),能飛行則可以實現這個介面,不能飛行就不實現這個介面。
2)設計層面不同,抽象類作為很多子類的父類,它是一種模板式設計。而介面是一種行為規範,它是一種輻射式設計。什麼是模板式設計?最簡單例子,大家都用過ppt裡面的模板,如果用模板A設計了ppt B和ppt C,ppt B和ppt C公共的部分就是模板A了,如果它們的公共部分需要改動,則只需要改動模板A就可以了,不需要重新對ppt B和ppt C進行改動。而輻射式設計,比如某個電梯都裝了某種報警器,一旦要更新報警器,就必須全部更新。也就是說對於抽象類,如果需要新增新的方法,可以直接在抽象類中新增具體的實現,子類可以不進行變更;而對於介面則不行,如果介面進行了變更,則所有實現這個介面的類都必須進行相應的改動。