明辉站/网站教程/内容

Java编程思想读书笔记(8章)

网站教程2024-05-19 阅读
[摘要]第8章 接口与内隐类    一. 接口    1. 如果实现接口的class未实现接口中的所有函数,则这个class必须被声明为abstractclass,而接口中未被实现的函数在这个class中为abstractclass。    interface Interface    public vo...
第8章 接口与内隐类

   一. 接口

   1. 如果实现接口的class未实现接口中的所有函数,则这个class必须被声明为abstractclass,而接口中未被实现的函数在这个class中为abstractclass。

   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) devricedclass可以同时继承多个interface和一个abstract或concretebaseclass。如果同时继承了baseclass和interface,那么要先写下具象类的名称,然后才是interfaces的名称。

   2) 如果derivedclass所继承的具象类具有与interfaces相同的函数,则可在derivedclass不实现那个函数。

   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);
   }
   }
   因为在ActionCharacterclass中有与接口CanFight完全相同的函数fight(),所以在Heroclass可以不实现fight()方法。当要调用x.fight()时,会调用ActionCharacterclass中的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中的函数看成是覆写classC中的函数,而不是象你想象中的作为实现接口中的函数的函数。

   (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());
   }
   }
   虽然Aclass含有接口,但它仍可被实例化,如(a)。

   由于接口B为private,所以在(b)处调用接口B时会出错。但当把接口B声明为public时,(b)将通过编译。但(c)处依然会出错,因为内隐类的作用域为定义该内隐类的外部类内(见内隐类)。

   2) 当接口嵌套于接口中

   1) 嵌套于接口中的接口自动为public,且只能为public。

   2) 当实现某个接口时,无需实现其中嵌套的接口。

   3) Private接口无法在其所定义的class之外被实现。

……

相关阅读