【JavaSE】抽象類、接口及兩者區別

概念部分

1 實際開發中不要去繼承實現好的類,而應該去繼續抽象類或者接口
2 抽象類
	普通類的基礎上擴充了一些抽象方法,即只聲明而未實現的方法
	抽象方法用abstract關鍵字聲明,不包含方法體,無具體實現,不能直接產生實例化對象。
	使用原則:
		必須有子類、子類必須覆寫所有抽象方法、方法覆寫的權限全用public;
		抽象類的對象可通過對象多態性利用子類爲其實例化。
		實例化子類時一定要先調用父類構造方法。
3 對象實例化
	核心步驟:類加載->類對象的空間開闢->類對象中的屬性初始化(構造方法)
4 模板設計模式
	模板方法定義了一個算法的步驟,並允許子類爲一個或多個步驟提供具體實現。
	最具代表性的是Servlet用。
	一個完整的模板模式超類定義:
	
	//基類聲明爲抽象類的原因是便於修改;其子類必須實現其具體操作
	abstract class AbstractClass{
		//模板方法,被聲明爲final以免子類改變這個算法的順序
		final void templateMethod(){
		
		}
		//具體操作延遲到子類中實現
		abstract void primitiveOperation1();
		abstract void primitiveOperation2();
		//具體操作且共用的方法定義在超類中,可以被模板方法或子類直接使用
		final void concreateOperation(){
			//實現
		}
		//鉤子方法是一類“默認不做事的方法”,子類可以視情況決定是否覆蓋它們。
		void hook(){
			//鉤子方法
		}
	}
	
5 接口
	可以約定子類的實現並且避免單繼承侷限。
	接口優先原則!
	接口就是一個抽象方法和全局常量(不常見)的集合。
	interface關鍵字定義,接口實現用implements關鍵字。
	一個子類可以實現多個接口。
	對於接口的子類必須覆寫接口中全部抽象方法,隨後可由子類向上轉型通過實例化子類來得到接口的實例化對象。
	接口中只允許public權限,無論屬性或方法。
	當子類需要同時實現接口和繼承抽象類時,先extends,再implements。
		例:class MessageImpl extends News implements IMessage
	實際開發中三大核心應用環境:
		定義操作標準、表示能力、分佈式開發中暴露遠程服務方法
6 工廠設計模式
	開發中程序的修改不應該影響客戶端,程序->JVM->操作系統,new是最大的耦合原因,解耦就要引入第三方Factory。
	JDK中用到工廠模式的典型操作:
		Collection中的iterator方法(集合類中的迭代器)
		java.util包中相關sql操作。
7 代理設計模式
	兩個子類共同實現一個接口,其中一個子類負責真實業務實現,另一個子類完成輔助真實業務主題的操作。
	本質:所有的真實業務操作都會有一個與之輔助的工具類共同完成。
8 抽象類與接口的區別***
	結構組成上:前者~普通類+抽象方法;後者~抽象方法+全局常量
	權限上:前者~各種權限;後者~僅可用public
	子類使用上:前者~extends繼承;後者~implements實現
	關係上:前者~一個抽象類可以實現若干個接口;後者~接口不能繼承抽象類,但接口可繼承多個父接口
	子類限制:前者~一個子類只能繼承一個;後者~一個子類可實現多個
	
	總結:開發中優先用接口,避免單繼承限制;抽象類是模板有層次感,接口更關心行爲與混合。

需記程序

1 寫星巴克師傅沖茶和泡咖啡的例子~模板模式方法
//首先是超類實現
abstract class CaffeineBeverage{
    //用final修飾主要是不想讓子類改變順序
    //這是一個整體的做飲料方法
    final void prepareRecipe(){
        boilWater();
        brew();
        pourInCup();
        //如果用戶想要才調用加調料方法
        if (customerWantsCondiments()){
            addCondiments();
        }
    }
    //寫出需要特殊實現的各個抽象方法
    abstract void brew();
    abstract void addCondiments();
    //這兩個方法時通用法,所以在超類中實現
    void boilWater(){
        System.out.println("Boiling Water...");
    }
    void pourInCup(){
        System.out.println("Pouring into cup...");
    }
    //鉤子方法,超類中通常是默認實現,子類可以選擇性覆寫
    boolean customerWantsCondiments(){
        return true;
    }
}
//子類實現
class Tea extends CaffeineBeverage{
    @Override
    void brew() {
        System.out.println("Steeping the tea...");
    }
    @Override
    void addCondiments() {
        System.out.println("Adding Lemon...");
    }
}
class Coffee extends CaffeineBeverage{
    @Override
    void brew() {
        System.out.println("Dripping Coffee through filter...");
    }
    @Override
    void addCondiments() {
        System.out.println("Adding Sugar and Milk...");
    }
    //在此覆寫鉤子函數,實現自定義功能
    public boolean customerWantsCondiments(){
        String answer = getUserInput();
        if (answer.equals("Y")){
            return true;
        }else {
            return false;
        }
    }
    private String getUserInput(){
        String answer = null;
        System.out.println("Can you want to add milk or sugar(Y/N)?");
        Scanner input = new Scanner(System.in);
        answer = input.nextLine();
        return answer;
    }
}
//測試類
public class Test{
    public static void main(String[] args) {
        CaffeineBeverage tea = new Tea();
        CaffeineBeverage coffee = new Coffee();
        System.out.println("\nMaking tea...");
        tea.prepareRecipe();
        System.out.println("\nMaking coffee...");
        coffee.prepareRecipe();
    }
}

2 寫多個子類實現一個接口的例子
//定義一個USB標準
interface USB{
    public void setup();    //安裝USB驅動
    public void work();     //進行工作
}
//定義電腦類
class Computer{
    public void plugin(USB usb){
        usb.setup();
        usb.work();
    }
}
//定義USB子類
class UDisk implements USB{
    @Override
    public void setup() {
        System.out.println("安裝U盤驅動");
    }
    @Override
    public void work() {
        System.out.println("U盤開始工作");
    }
}
class PrintDisk implements USB{
    @Override
    public void setup() {
        System.out.println("安裝打印機驅動");
    }
    @Override
    public void work() {
        System.out.println("打印機開始工作");
    }
}
public class Test{
    public static void main(String[] args) {
        Computer computer = new Computer();
        computer.plugin(new UDisk());
        computer.plugin(new PrintDisk());
    }
}

3 寫工廠設計模式,喫水果的例子
//定義一個喫水果的操作
interface IFruit{
    public void eat();
}
//定義工廠類
class Factory{
    public static IFruit getInstance(String className){
        if (className.equals("apple")){
            return new Apple();
        }
        if (className.equals("lemon")){
            return new Lemon();
        }
        return null;
    }
}
//子類實現
class Apple implements IFruit{
    @Override
    public void eat() {
        System.out.println("可以喫蘋果啦");
    }
}
class Lemon implements IFruit{
    @Override
    public void eat() {
        System.out.println("可以變成檸檬精啦");
    }
}
public class Test{
    public static void main(String[] args) {
        //如果沒有傳遞參數,工廠也不要生產
        if (args.length==0){
            System.out.println("沒有傳遞參數,程序退出");
            System.exit(1);     //退出程序
        }
        IFruit fruit = Factory.getInstance(args[0]);
        fruit.eat();
    }
}


4 寫代理設計模式,找代理買口紅的例子
interface ISubject{
    public void buyLipstick();  //核心功能是買口紅
}
//有目標要做事情的類,也就是買家
class RealSubject implements ISubject{
    @Override
    public void buyLipstick() {
        System.out.println("買三支紀梵希小羊皮");
    }
}
//做真實操作業務的類,也就是微信代理
class ProxySubject implements ISubject{
    private ISubject subject;   //真實業務對象
    //構造方法,確認當前對象
    public ProxySubject(ISubject subject){
        this.subject = subject;
    }
    public void produceLipstick(){
        System.out.println("生產紀梵希小羊皮三支");
    }
    public void aftersale(){
        System.out.println("紀梵希售後團隊");
    }
    @Override
    public void buyLipstick() {
        this.produceLipstick(); //真實業務前的準備,即先生產出口紅
        this.subject.buyLipstick(); //真實業務,代購去買口紅
        this.aftersale();   //操作後的首尾,口紅的售後問題
    }
}
class Factory{
    public static ISubject getInstance(){
        return new ProxySubject(new RealSubject());
    }
}
public class Test{
    public static void main(String[] args) {
        ISubject subject = Factory.getInstance();
        subject.buyLipstick();
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章