Java程式設計思想(2nd)學習筆記(8)-1 (轉)

worldblog發表於2007-08-17
Java程式設計思想(2nd)學習筆記(8)-1 (轉)[@more@]

第2章  介面與內隱類

一.  介面

1.  如果實現介面的class未實現介面中的所有,則這個class必須被宣告為abstract class,而介面中未被實現的函式在這個class中為abstract class。

interface Interface{

  public void f();

  public void g();

}

abstract class First implements Interface{

  public void f(){} 

}

class Second extends First{

  public void g(){}

}

public class ExplicitStatic{

  public static void main(String[] args){

  Interface f = new Second();

  f.f();

  f.g();

  }

}

2.  介面中的所有函式自動具有public訪問,所以實現某個介面時,必須將承襲自該介面的所有函式都定義為public

interface MyInterface {

  public void f();

  void g();

}

class First implements MyInterface {

  public void f(){}

  //!void g(){}出錯,應定義為public

}

3.  介面中的資料成員自動成為static和final

interface MyInterface{

  int i = 5;

  void f();

  void g();

}

class First implements MyInterface {

  public void f(){}

  public void g(){}

}

public class ExplicitStatic{

  public static void main(String[] args){

  MyInterface x = new First();

    // MyInterface的資料成員I為static,可直接

  System.out.println("MyInterface.i = " + MyInterface.i + " , x.i = " + x.i);

    // MyInterface的資料成員I為final,不能修改

  //x.i++;

  // MyInterface.i++;

  }

}

4.  多重繼承

1)  devriced class可以同時繼承多個interface和一個abstract或concrete base class。如果同時繼承了base class和interface,那麼要先寫下具象類的名稱,然後才是interfaces的名稱。

2)  如果derived class所繼承的具象類具有與interfaces相同的函式,則可在derived class不實現那個函式。

interface CanFight{

  void fight();

}

interface CanSwim{

  void swim();

}

class ActionCharacter{

  public void fight(){}  

}

class Hero extends ActionCharacter

  implements CanFight, CanSwim{

  public void swim(){};

}

public class ExplicitStatic{

  static void f(CanFight x) { x.fight(); }

  static void s(CanSwim x) { x.swim(); }

  static void a(ActionCharacter x) { x.fight(); }

  static void h(Hero x){

  x.fight();  x.swim(); 

  }

  public static void main(String[] args){

  Hero h = new Hero();

  f(h); s(h); a(h); h(h);

  }

}

因為在ActionCharacter class中有與介面CanFight完全相同的函式fight(),所以在Hero class可以不實現fight()方法。當要呼叫x.fight()時,會呼叫ActionCharacter class中的fight()函式。

3)  介面的合併時的名稱衝突問題

interface I1 { void f(); }

interface I2 { int f(int i); }

interface I3 { int f(); }

class C { public int f() { return 1; } }

 :namespace prefix = o ns = "urn:schemas--com::office" />

class C2 implements I1, I2{

  public void f() {}

  public int f(int i) { return 1; }

}

class C3 extends C implements I2{

  public int f(int i) { return 1; }

}

class C4 extends C implements I3{

  public int f() { return 1; }

}

//class C5 extends C implements I1{} a

//class C6 extends C implements I1{ public void f(){} } b

interface I4 extends I1, I3{} //(c

class C7 implements I4{

  public void f() {}

  public int f() { return 1; }

}

(a處程式碼會產生以下錯誤: method f() in class C cannot implement method f() in interface I1 with different return type, was void。

(b處程式碼也是錯誤的: method f() in class C6 cannot overr method f() in class C with different return type, was int。由(b)處程式碼也可看出,雖然你試圖實現介面I1中的函式,但由於extends C在前,所以會把C6中的函式看成是覆寫class C中的函式,而不是象你想象中的作為實現介面中的函式的函式。

(c處程式碼在原書中(P253)說會出錯,但我在測試時並沒發生錯誤。但當你試圖透過C7來實現介面I4時,是無論如何也不可能編譯透過的。

4)  中唯一可以使用多重繼承的地方

Java是不允許透過關鍵字extends來實現多重繼承的,但除了透過多重繼承來擴充介面除外。

interface I1{

  void f1();

}

interface I2{

  void f2();

}

interface Ie1 extends I2{

  void fe1();

}

class Ce1 implements Ie1{

  public void f2() {}

  public void fe1() {}

}

interface Ie2 extends Ie1, I1{

  void fe2();

}

class Ce2 implements Ie2{

  public void fe2() {}

  public void f2() {}

  public void fe1() {}

  public void f1() {}

}

介面Ie2繼承了兩個介面。     

5.  巢狀的interfaces

巢狀的interfaces可以在定義該內部介面的外部類(介面)之外被使用(但內隱類不行)。

1)  當介面巢狀於class中

a)  不論介面為public、friendly或private,都可被實現為public、friendly、private三種巢狀類。

b)  被宣告為private的介面不能在class外被使用。

class A{

  private interface B{

  void f();

  }

  public class BImp implements B{

   public void f() {}

  }

  private class BImp2 implements B{

  public void f() {}

  }

  public B getB() { return new BImp(); }

  private B dRef;

  public void recivedD(B d){

  dRef = d;

  dRef.f();;

  }

}

public class ExplicitStatic{

  public static void main(String[] args){

  A a = new A(); //(a

  //A.B ab = a.getB(); b

  //A.BImp = a.getB(); c

a.recivedD(a.getB());

  }

}

雖然A class含有介面,但它仍可被例項化,如(a)。

由於介面B為private,所以在(b)處呼叫介面B時會出錯。但當把介面B宣告為public時,(b)將透過編譯。但(c)處依然會出錯,因為內隱類的作用域為定義該內隱類的外部類內(見內隱類)。

2)  當介面巢狀於介面中

1)  巢狀於介面中的介面自動為public,且只能為public。

2)  當實現某個介面時,無需實現其中巢狀的介面。

3)  Private介面無法在其所定義的class之外被實現。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-963528/,如需轉載,請註明出處,否則將追究法律責任。

相關文章