抽象類
使用abstract關鍵字修飾的類叫做抽象類
定義抽象類的語法格式: [訪問修飾符] abstract class <類名>
普通類可以實例化,抽象類不能實例化,但是可以創建子類實例對象。
使用abstract關鍵字修飾的方法叫做抽象方法
定義抽象類的語法格式: [訪問修飾符] abstract <返回值類型><方法名>([參數列表])
普通方法有方法體,抽象方法沒有方法體。
幾個要點:
- 抽象方法只能定義在抽象類里。也就是說有抽象方法的類一定是抽象類,抽象類不一定有抽象方法。
- 抽象類可以和普通類一樣包含各類型的成員,包括屬性和方法。
- 如果子類沒有實現父類所有的抽象方法,子類必須被定義為抽象類
- 沒有抽象構造方法,也沒有抽象靜態方法
- 抽象類中可以有非抽象的構造方法,創建子類實例時可能調用,繼承樹的頂層一般是抽象類
示例:
public abstract class Person{ //定義了抽象類
String name; //在抽象類中可以定義成員變量
private int age;
public abstract void eat(); //在抽象類中可以定義抽象方法,抽象方法沒有方法體
public void sleep(){ //在抽象類中也可以定義普通方法
System.out.print("正在睡覺......");
}
}
class Test{
public static void main(String[] args) {
Person p = new Person(); //這種寫法是錯誤的,抽象類不能直接被實例化,只能實例化子類對象
}
}
接口
接口(interface)是一系列方法的聲明,是抽象方法的集合。一個接口只有方法的特征,沒有方法的實現。
面向接口編程就是只關心實現類有何能力,不關心實現細節;面向接口的約定,不考慮接口的具體實現。
接口是一種功能,是一種能力。一個類可以實現一個接口,使用關鍵字implements,實現一個接口就必須實現接口里聲明的方法。如果說繼承是一種
is a
的關系,那么接口就是一種has a
的關系,實現一個接口就是擁有某種能力。接口是一種標識,是一種約束。一個接口可以只有一個名字,接口里面什么也沒有,方法的聲明也沒有,這種接口叫做標識接口,作用是標識一種身份。如java中的Serializalbe接口,接口里面什么也沒有,只實現了這個接口,才能被序列化。
接口和類相似,但他們是不同的概念,類描述對象的屬性和方法; 接口聲明了一些方法的特征。
public interface MyInterface{ //定義一個接口
public static final COUNT = 100; //定義一個變量,只能是靜態常量
public abstract void eat(); //定義一個方法,只能是public的抽象方法
}
//一個類只能繼承一個父類,但是可以實現多個接口
class Studnet extends Person implements A,B,C{
}
接口示例:
public interface Lock {//定義一個接口,功能是上鎖和開鎖
public void lock();
public void unlock();
}
public interface Camera {//定義一個接口,功能是拍照
public void takePhoto();
}
public abstract class Gate {//定義一個抽象類,門
public abstract void open();//定義抽象方法,開門和關門
public abstract void close();
}
//防盜門類,繼承門類,實現鎖和拍照功能
class ProofGate extends Gate implements Lock,Camera{
//實現抽象類的方法
public void open() {
System.out.println("門開了");
}
public void close() {
System.out.println("門關了");
}
//實現接口中聲明的方法
public void lock() {
System.out.println("門鎖了");
}
public void unlock() {
System.out.println("門開鎖了");
}
public void takePhoto() {
System.out.println("拍一下張來訪者照片");
}
}
class Test {
public static void main(String[] args) {
ProofGate pg = new ProofGate();
pg.close();
pg.lock();
pg.takePhoto();
pg.unlock();
pg.open();
}
}
標識接口示例:
public interface Human {//定義一個標識接口,標識人類
}
public interface Animal {//定義一個標識接口,標識動物
}
class Chinese implements Human{//實現標識接口
}
class American implements Human{//實現標識接口
}
class Wolf implements Animal{//實現標識接口
}
class Bear implements Animal{//實現標識接口
}
class Hunt {
void hunt(Object obj){
//用標識判斷識別身份,是人類就不能開槍
if(obj instanceof Human){
System.out.println("不能開槍,這是人類");
}else if(obj instanceof Animal){ //是動物就開槍
System.out.println("砰砰砰,開槍......"+obj.getClass().getName()+"被打死了");
}
}
public static void main(String[] args) {
Hunt hunt = new Hunt();
Chinese man1 = new Chinese();
American man2 = new American();
Wolf wolf = new Wolf();
Bear bear = new Bear();
hunt.hunt(man1);
hunt.hunt(man2);
hunt.hunt(bear);
hunt.hunt(wolf);
}
}
幾個要點:
- 接口沒有構造方法,無法被實例化,接口不是被類繼承,而是可以被類實現。
- 接口類型可用來聲明一個變量,指向此接口實現的對象,也就是接口可以實例化它的實現類的對象。
- 接口中不能有方法的實現。
- 接口中所有的變量會被隱式的指定為 public static final 變量(并且只能是 public);接口中的方法會被隱式的指定為 public abstract (只能是 public abstract,其他修飾符都會報錯)。
- 實現類必須實現接口的所有方法,否則就必須聲明為抽象類。
- 實現類可以實現多個接口,可以理解為JAVA中的多繼承。
抽象類和接口的區別
相同點:
- 都代表了系統的抽象層,都很抽象
- 都不能被實例化
- 都能包含抽象方法
不同點:
- 抽象類中可以為部分方法提供默認實現,接口中只包含抽象方法,沒有方法的實現。
- 一個類只有一個直接父類,但一個類可以實現多個接口。
- 已經存在的繼承樹,可以方便的抽取接口,擔抽取抽象類不容易。