接口與內部類


1.接口

首先接口不是類,而是對類的一組需求描述。下面是泛型類型的接口代碼

public interface Comparable<T>

{

int compareTo(T other);

}

接口中的所有方法自動屬於public,在接口中聲明方法,不必提關鍵字public。注意,接口中不能提供實例域和方法實現,這些必須由實現接口的那個類來完成。

這里簡單舉例說明下實例域的概念:

舉個例子:人類是一個類,張三就是人類的一個實例。
人類都有手、腳,可以理解為 人類的域。
張三的手、腳就是張三這個實例的自己的私有的域,比如張三有一個手指是斷的,不能說人類的手

這里接口和沒有實例域的抽象類類似,但它們還是有所區別。有如下區別:

1.接口是公開的,里面不能有私有的方法或變量,是用於讓別人使用的,而抽象類是可以有私有方法或私有變量的。

2.接口可以實現多重繼承,而一個類只能繼承一個超類,但可以通過繼承多個接口實現多重繼承。

3.接口可以多繼承,抽象類不行。

4.接口中基本數據類型為static 而抽類象不是的。

以下是實現接口方法的語句(注意:在現實接口時,必須把方法聲明為public,否則,編譯器將認為這個方法的訪問屬性是包可見性,即類的默認訪問屬性,之后編譯器就會給出試圖提供更弱的訪問權限的警告信息):

class Employee implements Comparable<Employee>

{

public int compareTo(Employee other)

{

return Double.compare(salary,other.salary);

}

}

我們再來看接口的一些特性:

1.接口不是類,所以不能用x=new Comparable(...);來實例化一個接口,但可以先聲明一個接口變量,再對其進行類的實例化。

Comparable x;

x=new Employee(...);

2.我們可以用一下語句來檢查對象是否實現了某個特定的接口:

if(anObject instanceof Comparable){...}

3.接口也可以擴展

public interface Moveable

{

void move(double x,double y);

}

public interface Powered extends Moveable

{

doble milePerGallon();

}

public interface Powered extends Moveable{

double milesPerGllon();

double SPEED_LIMIT=95;//a public static final constant,接口中的域將被自動設為public static final.

2.內部類

定義在另一個類中的類,稱為內部類。

1.內部類可以對同一個包中的其他類隱藏起來。 (一般的非內部類,是不允許有 private 與protected權限的,但內部類可以)

2.內部類方法可以訪問外圍類中定義所在作用域中的數據,包括私有的數據。

3.可以實現多重繼承

4.可以避免修改接口而實現同一個類中兩種同名方法的調用。

5.當想要定義一個回調函數且不想編寫大量代碼時,使用匿名內部類比較便捷。

 內部類嵌套類的兩個重要作用是:命名控制和訪問控制

看下面這個C++嵌套類的例子:

Class LinkedList

{

public:

       class Iterator

{

public:

    void insret(int x);

    int erase();

     ...

};

private:

    class Link

{

public:

      Link*next;

      int data;

}

...

};

Iterator被嵌套在LinkedList類內部,我們可以用LinkedList::Iterator的方式命名來避免與其他名為Iterator的類重復。

即使Link的數據域被設計為公有的,它仍然安全,只能被LinkedList中的方法訪問。

注意,JAVA中的內部類還有另外一個功能,內部類的對象有一個隱式引用,通過這個指針可以訪問外圍類對象的全部狀態。請看下面的java內部類的例子:

public class TalkingClock

{

private int interval;

private boolean beep;

public TalkingClock(int interval,boolean beep){...}

public void start(){...}

public class TimePrinter implements ActionListerner

{

public void actionPerformed(ActionEvent event)

{

Date now=new Date();

System.out.println("At the tone,the time is"+now);

if(beep)Toolkit.getDefaultToolkit().beep();//我們把外圍類對象的引用稱為outer,所以該語句等價於if(outer.beep)Toolkit.getDefaultTookit().beep();

//使用外圍類引用的正規語法還要復雜一些。表達式為:OuterClass.this,所該語句可以改寫為if(TalkingClock.this.beep)Toolkit.getDefaultTookit().beep();

}

}

從上面的例子看出,內部類可以訪問自身的數據域,也可以訪問創建它的外圍類對象的數據域。注意可以用outerObject.new Inner(construction paramenters)

來編寫內部對象的構造器。同樣可以用OuterClass.InnerClass的語法來引用內部類。

我們繼續來看下面這個局部內部類

public void start()//我們把該語句改成public void start(int interval,final boolean beep), 這樣局部類不僅能訪問它們的外部類,還可以訪問局部變量,注意局部變量必須被

//聲明為final,局部變量的訪問非常容易,它減少了需要顯示編寫的實例域,從而使得內部類更加簡單。

{

class TimePrinter implements ActionListener

{

public void actionPerformed(ActionEvent event)

{

Date now=new Date();

System.out.println("At the tone,the time is"+now);

if(beep) Toolkit.getDefaultTookit().beep();

}

}

ActionLister listener=new TimePrinter();

Time t=new Timer(interval,listener);

t.start();

}

注意局部類不能用public或者private訪問說明符進行聲明,它的作用域被限定在聲明這個局部類的塊中。因此,它有一個更大的優勢是,對外部世界完全的隱藏起來,

除start方法之外,沒有任何方法知道TimePrinter類的存在。

匿名內部類

創建這個類的一個對象,就不必命名了,我們稱為匿名內部類。

public void start(int interval,final boolean beep)

{

ActionListener listener=new ActionListener()

{

public void actionPerformed(ActionEvent event)

{

Date now=new Date();

System.out.println("At the tone,the time is"+now);

if(beep)Toolkit.getDefaultToolkit().beep();

}

};

Timer t=new Timer(interval,listener);

t.start();

}

注意匿名類沒有類名,而構造器的名字必須域類名相同,所以匿名類沒有構造參數。

靜態內部類

如果我們僅僅想把一個類隱藏在另一個類中,而不需要引用外部對象,可以將內部類聲明為static,以便取消產生引用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM