1. 程式人生 > >Java程式設計思想第四版讀書筆記——第九章 介面

Java程式設計思想第四版讀書筆記——第九章 介面

這章介紹了介面卡設計模式和策略設計模式。

第九章  介面

介面和內部類為我們提供了一種將介面與實現分離的更加結構化的方法。

1、抽象類和抽象方法

public abstract void f();

建立抽象類是希望通過這個通用介面操縱一系列類。如果一個類包含大於等於一個抽象方法,那麼這個類就是抽象類,必須用abstract關鍵字來限定這個抽象類。

如果試圖直接建立該抽象類的物件,編譯器會報錯。

如果抽象類的子類沒有為基類的抽象方法提供定義,那麼這個匯出類依舊是抽象類。

抽象類也可以不包含任何抽象方法,單純的用abstract限定類。(該類不能產生物件)

2、介面

interface這個關鍵字替代class關鍵字,產生了一個完全抽象的類。介面只提供形式,未提供任何具體實現。

介面被用了建立類與類之間的協議。介面也可以包含域,但是這些域隱式的是static和final的。因此,其中定義的成員變數,是static&final的。

implenments關鍵字可以跟一組介面,extends關鍵字只能跟一個基類。

介面中的方法必須是public的,隱式的被宣告public的,如果要顯示宣告,它們也必須被宣告為public的。否則在繼承的過程中,可訪問許可權被降低,這是java編譯器所不允許的。

3、完全解耦

策略設計模式:建立一個能夠根據傳遞引數物件不同而具有不同行為的方法。比如:

package interfaces.classprocessor; import java.util.*; import static net.mindview.util.Print.*; class Processor { public String name() { return getClass().getSimpleName(); } Object process(Object input) { return input; } } class Upcase extends Processor { String process(Object input) { // Covariant return return ((String)input).toUpperCase(); } } class Downcase extends Processor { String process(Object input) { return ((String)input).toLowerCase(); } } class Splitter extends Processor { String process(Object input) { // The split() argument divides a String into pieces: return Arrays.toString(((String)input).split(" ")); } } public class Apply { public static void process(Processor p, Object s) { print("Using Processor " + p.name()); print(p.process(s)); } public static String s = "Disagreement with beliefs is by definition incorrect"; public static void main(String[] args) { process(new Upcase(), s); process(new Downcase(), s); process(new Splitter(), s); } } /* Output: Using Processor Upcase DISAGREEMENT WITH BELIEFS IS BY DEFINITION INCORRECT Using Processor Downcase disagreement with beliefs is by definition incorrect Using Processor Splitter [Disagreement, with, beliefs, is, by, definition, incorrect] 4、java中的多重繼承

java沒有任何與介面相關的儲存,因此可以繼承任意多個介面。\

使用介面的核心原因:為了能夠向上轉型為多個基本型別。順帶可以防止客戶端程式設計師建立該類的物件。

5、通過繼承擴充套件介面

extends只能用於單一類,但是介面繼承時卻可以引用多個介面,用逗號分開。

interface Interface1 extends Interface2,Interface3{}   

介面無法用implements來實現別的介面,必須用extends。

應該儘量避免組合的多個介面中包含相同方法名,這樣會造成程式碼可讀性的混亂。

6、適配介面

類的構造器接受一個介面,將希望使用該類的類都實現該介面,這樣可以類就可以作用於更多的型別。比如Scanner類,想使用該類的型別

和策略模式的不同:

方法可以作用於不同的型別。

而介面卡模式是,將不同型別作為類構造器的引數傳入,有點類已經固定了,等著別人用的時候向下轉型成介面類的感覺。

7、介面中的域

介面中的域是static&final的,所以常量初始化值會用大寫字母的風格。

package interfaces; public interface Months { int JANUARY = 1, FEBRUARY = 2, MARCH = 3, APRIL = 4, MAY = 5, JUNE = 6, JULY = 7, AUGUST = 8, SEPTEMBER = 9, OCTOBER = 10, NOVEMBER = 11, DECEMBER = 12; }

但是一般不這麼做,在介面中定義常量,而是用enum關鍵字實現。

介面中定義的常量一定要初始化,不能出現空final,但是可以被非常量表達式初始化。

8、巢狀介面

巢狀在另一個介面中的介面自動是public的,而不能宣告為private的.

當實現某個介面是,並不需要實現巢狀在其內部的任何藉口,而且,private介面不能在定義它的類之外被實現。

9、介面與工廠

工廠設計模式:

在工廠物件上呼叫建立方法,該工廠物件將生成介面的某個實現物件。這樣將程式碼與介面實現分離,這樣使得我們可以透明的將某個實現替換成另一個實現。

import static net.mindview.util.Print.*; interface Service { void method1(); void method2(); } interface ServiceFactory { Service getService(); } class Implementation1 implements Service { Implementation1() {} // Package access public void method1() {print("Implementation1 method1");} public void method2() {print("Implementation1 method2");} } class Implementation1Factory implements ServiceFactory { public Service getService() { return new Implementation1(); } } class Implementation2 implements Service { Implementation2() {} // Package access public void method1() {print("Implementation2 method1");} public void method2() {print("Implementation2 method2");} } class Implementation2Factory implements ServiceFactory { public Service getService() { return new Implementation2(); } } public class Factories { public static void serviceConsumer(ServiceFactory fact) { Service s = fact.getService(); s.method1(); s.method2(); } public static void main(String[] args) { serviceConsumer(new Implementation1Factory()); // Implementations are completely interchangeable: serviceConsumer(new Implementation2Factory()); } } /* Output: Implementation1 method1 Implementation1 method2 Implementation2 method1 Implementation2 method2 對消費者傳遞一個工廠1物件,產生工廠1的產品,呼叫產品1的方法。

對消費者傳遞一個工廠2物件,產生工廠2的產品,呼叫產品2的方法。