第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; } } 
  
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 override method f() in class C with different return type, was int。由(b)处代码也可看出,虽然你试图实现接口I1中的函数,但由于extends C在前,所以编译器会把C6中的函数看成是覆写class C中的函数,而不是象你想象中的作为实现接口中的函数的函数。 
(c)处代码在原书中(P253)说会出错,但我在测试时并没发生错误。但当你试图通过C7来实现接口I4时,是无论如何也不可能编译通过的。 
4)        Java中唯一可以使用多重继承的地方 
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之外被实现。  
 
  |