天天看點

再看抽象類與接口

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

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

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");

         }

<b>思考:</b>

       張三去酒會參加活動,碰見了一個美國女孩,想跟她說“HELLO,MAKE 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!") ;

       現在孫鍵欠了我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("要準備繩索、刀子、槍支。。。") ;

                   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() ;

       問題的引出:現在使用一個接口,同時定義出子類,通過子類為接口進行執行個體化:

interface Fruit{

         public void eat() ;

class Apple implements Fruit{

         public void eat(){

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

public class Demo07{

                   Fruit f = new Apple() ;

                   f.eat() ;

       以上代碼存在問題?

              · main方法實際上相當于是一個用戶端程式

              · 如果現在需要換一個子類了,那麼就要修改用戶端。

              · 好的程式:某一處的更改不影響調用處

       造成以上問題的根源:

              · 子類直接在用戶端使用,耦合度太深了。

       在對象執行個體化的中間加入一個過渡端,所謂的解耦合最大的特點就是永遠有一個過渡端。

       那麼現在加入一個過渡端:

class Cherry implements Fruit{

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

<b>class Factory{</b>

<b>         public static Fruit getInstance(String str){</b>

<b>                   Fruit f = null ;</b>

<b>                   if("apple".equals(str)){</b>

<b>                            f = new Apple() ;</b>

<b>                   }</b>

<b>                   if("cherry".equals(str)){</b>

<b>                            f = new Cherry() ;</b>

<b>                   return f ;</b>

<b>         }</b>

<b>};</b>

public class Demo08{

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

                   if(f!=null)

                            f.eat() ;

       此時,發現程式的用戶端沒有任何的改變,而直接可以選擇各種所要的子類。那麼通過工廠取得全部的接口執行個體,那麼以後修改的時候就可以隻修改工廠了。

<b>差別點</b>

<b>抽象類</b>

<b>接口</b>

<b>定義</b><b></b>

abstract class 抽象類名稱{}

interface 接口名稱{}

<b>概念</b><b></b>

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

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

<b>使用</b><b></b>

需要通過子類繼承

class 子類 extends 父類

需要通過子類實作

class 子類 implements 接口

<b>關系</b><b></b>

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

<b>作用</b><b></b>

提供了一個模闆

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

<b>設計模式</b><b></b>

模闆設計模式

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

擴充卡設計模式

<b>限制</b><b></b>

抽象類有單繼承局限

無此局限

<b>應用</b><b></b>

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

<b>特殊點</b><b></b>

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

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

<b>特殊點:</b>

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、  一個接口中能否包含一個抽象類?可以

         abstract class B{

                   public abstract void printB() ;

class DA implements A{

         class DB extends B{

觀察以下的題目,寫出輸出結果:

         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”。

本文轉自 李興華 51CTO部落格,原文連結:http://blog.51cto.com/lixinghua/96923,如需轉載請自行聯系原作者

繼續閱讀