再看抽象類與接口

3.1、抽象類與接口(

       抽象類更多的情況下是作爲一個模板使用,而接口更多的情況下是作爲一個標準出現。

3.1.1、適配器設計

       一個子類如果實現了一個接口,則肯定要覆寫接口中的全部方法,那是否有一種方式,可以讓子類有選擇的去實現接口中的方法,而不是全都實現呢?
interface A{

         public void printA() ;

         public void printB() ;

         public void printC() ;

         public void printD() ;

         public void printE() ;

}

       以上的接口的子類能否有選擇性的進行所需要方法的覆寫呢?
interface A{

         public void printA() ;

         public void printB() ;

         public void printC() ;

         public void printD() ;

         public void printE() ;

}

abstract class AAdapter implements A{

         // 方法全部實現

         // 但是此類是中間過渡類,不能直接使用,所以此時應該把此類定義成抽象類。

         public void printA() {}

         public void printB() {}

         public void printC() {}

         public void printD() {}

         public void printE() {}

};

class AAA extends AA{

         public void printA() {

                   System.out.println("dafa");

         }

};

思考:

       張三去酒會參加活動,碰見了一個美國女孩,想跟她說“HELLOMAKE FRIEND”,第二次又參加了一個舞會,又碰見了一箇中國的女孩,想跟她說“你好,我想跟你交朋友”。
       · 碰見美國人說英語
       · 碰見中國人說中文
       · 接口的第二個作用就是表示一種能力。
interface SayChina{

         public void sayChina() ;

}

interface SayEnglish{

         public void sayEnglish() ;

}

class Person implements SayChina,SayEnglish{

         public void sayChina(){

                   System.out.println("你好,交朋友吧!") ;

         }

         public void sayEnglish(){

                   System.out.println("HELLO,MAKE FRIEND!") ;

         }

};

3.1.2、代理設計

思考:

       現在孫鍵欠了我500000000元錢,此時,王寧是一個老實人,孫鍵欺負他,不還,之後王寧沒有辦法了,找到了王偉(專門的討債公司),準備好了繩索、刀子、槍支,從孫鍵手裏把銀子要了回來,之後銷燬了一切的證據。但是王寧只管拿回了自己的錢。
       可以按照以下的形式組織代碼:
interface Subject{

         public void giveMoney() ;

}

class RealSubject implements Subject{

         public void giveMoney(){

                   System.out.println("把錢拿回。。。") ;

         }

};

class ProxySubject implements Subject{

         private Subject sub = null ;

         public ProxySubject(Subject sub){

                   this.sub = sub ;

         }

         public void before(){

                   System.out.println("要準備繩索、刀子、槍支。。。") ;

         }

         public void giveMoney(){

                   this.before() ;

                   this.sub.giveMoney() ;

                   this.after() ;

         }

         public void after(){

                   System.out.println("銷燬一切的罪證。。。") ;

         }

};

public class Demo06{

         public static void main(String args[]){

                   Subject sub = new ProxySubject(new RealSubject()) ;

                   sub.giveMoney() ;

         }

};

3.1.3、工廠設計

       問題的引出:現在使用一個接口,同時定義出子類,通過子類爲接口進行實例化:
interface Fruit{

         public void eat() ;

}

class Apple implements Fruit{

         public void eat(){

                   System.out.println("吃蘋果。。。") ;

         }

};

public class Demo07{

         public static void main(String args[]){

                   Fruit f = new Apple() ;

                   f.eat() ;

         }

};

       以上代碼存在問題?
              · main方法實際上相當於是一個客戶端程序
              · 如果現在需要換一個子類了,那麼就要修改客戶端。
              · 好的程序:某一處的更改不影響調用處
       造成以上問題的根源:
              · 子類直接在客戶端使用,耦合度太深了。
       在對象實例化的中間加入一個過渡端,所謂的解耦合最大的特點就是永遠有一個過渡端。
       那麼現在加入一個過渡端:
interface Fruit{

         public void eat() ;

}

class Apple implements Fruit{

         public void eat(){

                   System.out.println("吃蘋果。。。") ;

         }

};

class Cherry implements Fruit{

         public void eat(){

                   System.out.println("吃櫻桃。。。") ;

         }

};

class Factory{

         public static Fruit getInstance(String str){

                   Fruit f = null ;

                   if("apple".equals(str)){

                            f = new Apple() ;

                   }

                   if("cherry".equals(str)){

                            f = new Cherry() ;

                   }

                   return f ;

         }

};

public class Demo08{

         public static void main(String args[]){

                   Fruit f = Factory.getInstance(args[0]) ;

                   if(f!=null)

                            f.eat() ;

         }

};

       此時,發現程序的客戶端沒有任何的改變,而直接可以選擇各種所要的子類。那麼通過工廠取得全部的接口實例,那麼以後修改的時候就可以只修改工廠了。

3.1.4、抽象類與接口的區別(☆☆

區別點

抽象類

接口

定義

abstract class 抽象類名稱{}

interface 接口名稱{}

概念

包含一個抽象方法的類就是抽象類,除此之外還包含常量、變量、普通方法、構造方法

只包含全局常量和抽象方法的類稱爲接口

使用

需要通過子類繼承

class 子類 extends 父類

需要通過子類實現

class 子類 implements 接口

關係

一個抽象類可以實現多個接口,一個接口不能繼承一個抽象類

作用

提供了一個模板

提供了一個標準,或者說表示了一種能力

設計模式

模板設計模式

工廠設計模式、代理設計模式

適配器設計模式

限制

抽象類有單繼承侷限

無此侷限

應用

如果抽象類與接口同時都可以使用,優先使用接口

特殊點

一個抽象類可以包含一個接口或一個抽象類

一個接口中也可以包含抽象類或接口

 

特殊點:

1  一個抽象類中能否包含一個接口?可以
abstract class A{

         public abstract void printA() ;

         interface B{

                   public void printB() ;

         }

};

class DA extends A{

         public void printA(){}

         class DB implements B{

                   public void printB(){}

         };

};

2  一個接口中能否包含一個抽象類?可以
interface A{

         public abstract void printA() ;

         abstract class B{

                   public abstract void printB() ;

         }

};

class DA implements A{

         public void printA(){}

         class DB extends B{

                   public void printB(){}

         };

};

觀察以下的題目,寫出輸出結果:
abstract class A{

         public A(){

                   this.print() ;

         }

         public abstract void print() ;

}

class B extends A{

         private int i = 10 ;

         public B(int i){

                   this.i = i ;

         }

         public void print(){

                   System.out.println(this.i) ;

         }

};

public class Demo11{

         public static void main(String artgs[]){

                   new B(100) ;

         }

};

       答案是0
       子類對象實例化之前,肯定要先去調用父類中的無參構造方法,爲父類中的屬性初始化,但是父類中的方法未調用完之前,子類的內容並沒有初始化,如果沒有初始化,則會安排默認值,默認值就是“0
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章