«August 2025»
12
3456789
10111213141516
17181920212223
24252627282930
31


公告
欢迎大家访问,希望大家多多交流!
    Email:hello105@ustc.edu
    QQ: 7779112
    

我的分类(专题)

首页(63)
Xml收藏(3)
Java收藏(17)
心情(11)
其他(32)


最新日志
DataStage 开发中遇到的几个问题
Tar的详细用法(转自Linux伊甸园)
UNIX常用命令-目录及文件操作命令(z
The 38 Subsystems of
DataStage安装
回来了!
rpm使用
学校好冷清阿
科大怪谈(1)
科大怪谈(2)

最新回复
回复:DataStage 开发中遇到的几
回复:DataStage 开发中遇到的几
回复:发放WALLOP邀请
回复:发放WALLOP邀请
回复:发放WALLOP邀请
回复:发放WALLOP邀请
回复:发放WALLOP邀请
回复:发放WALLOP邀请
回复:发放WALLOP邀请
回复:发放WALLOP邀请

留言板
签写新留言

为什么?
回学校了
关于wallop

统计
blog名称:hello105
日志总数:63
评论数量:174
留言数量:3
访问次数:395844
建立时间:2004年11月8日

链接

Lost Ferry

 




W3CHINA Blog首页    管理页面    写新日志    退出

[Java收藏]Java编程思想读书笔记-2(第8章)(zz)
音乐昆虫 发表于 2004/12/6 22:15:13

第8章    接口与内隐类 一.    接口 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之外被实现。 二.    Inner classes(内隐类) 1.    内隐类的基本用法 1)    如果要在外围class的non-static函数之外产生一个inner class 对象,得以OuterClassName.InnerClassName的形式指定该对象的型别。而在non-static函数内则不用。 public class ExplicitStatic{     class Contents{         private int i = 11;         public int value() { return i; }     }     class Destination{         private String label;         Destination(String whereTo){             label = whereTo;         }         String readLabel() { return label; }     }     public Destination to(String s){     //在outer class的non-static函数中可直接产生inner class对象         return new Destination(s); //(1)     }     public Contents cont(){         return new Contents(); //(1)     }     public void ship(String dest){ //在outer class的non-static函数中可直接通过InnerClassName //来指定对象型别         Contents c = cont();         Destination d = to(dest);         System.out.println(d.readLabel());     }     public static void main(String[] args){         ExplicitStatic p = new ExplicitStatic();         p.ship("Tanzania");         ExplicitStatic q = new ExplicitStatic();    //在outer class的非non-static函数内产生inner class对象         ExplicitStatic.Contents c = q.cont();         ExplicitStatic.Destination d = q.to("Borneo");   //不能在static函数直接生成inner class对象         // new Contents();     } } 2)    对于non-static inner class,在外围class的non-static函数 可以通过new产生一个inner class对象,如上面的(1)处。但要在非non-static函数产生一个inner class对象,则一定要 关联到其enclosing class的某个对象。 3)    inner class的向上转型 当把一个inner class对象向上转型成为interface时,我们得到的只是一个reference。 interface Destination{     String readLabel(); } interface Contents{     int value(); } class Parcel3{     private class PContents implements Contents{         private int i = 11;         public int value() { return i; }     }     protected class PDestination implements Destination{         private String label;         PDestination(String whereTo){             label = whereTo;         }         public String readLabel() { return label; }     }     public Destination to(String s){         return new PDestination(s);     }     public Contents cont(){         return new PContents();     } } public class ExplicitStatic{         public static void main(String[] args){         Parcel3 p = new Parcel3();         //把inner class对象向上转型         Contents c = p.cont();         Destination d = p.to("Borneo");             } } 虽然我们不能在ExplicitStatic class无法调用Pcontents class,但我们把一个Pcontents class对象向上转型为Contents,就可对之进行调用。 4)    inner class的作用域为定义该inner class的scope内。但inner class可在它的作用域之外被继承(见4)。 interface Contents{     int value(); } class Parcel3{     //PContents1 class的作用域为Parcel3 class内     private class PContents1 implements Contents{         private int i = 11;         public int value() { return i; }     }     public Contents cont1(){         return new PContents1();     }     public Contents cont2(){         //PContents2 class的作用域为函数cont2内         class PContents2 implements Contents{             private int i = 11;             public int value() { return i; }         }         return new PContents2();     }     //不能在函数cont2外使用PContents2 class     /*     public Contents cont22(){         return new PContents2();     }     */     public Contents cont3(boolean b){         if(b){             //PContents3 class的作用域为当前if内             class PContents3 implements Contents{                 private int i = 11;                 public int value() { return i; }             }             return new PContents3();         }         //不能在if外使用PContents3 class         //return new PContents3();         return null;     }  } public class ExplicitStatic{         public static void main(String[] args){         Parcel3 p = new Parcel3();         Contents c1 = p.cont1();         Contents c2 = p.cont2();         Contents c3 = p.cont3(true);     } } 2.    内隐类与外围enclosing  class的连接关系 2.1 non-static inner class 1)    inner class可以访问enclosing class的所有成员(包括private成 员),就像inner class自己拥有这些成员一样。即inner class天生具有对enclosing class的所有成员的访问权力。 2)     Inner class对象被产生时,一定要关联到其enclosing class的某个对象(这个enclosing class对象就是 Inner class对象的制造者)。建构inner class对象的同时,得有其enclosing class对象的reference才行。 原 因:因为inner class可以访问enclosing class的所有成员,那么当产生一个inner class时,编译器会自动为inner  class对象添加一个指向enclosing class对象的reference(这个reference是隐藏的)。所以Inner class 被产生时,一定要关联到其enclosing class的某个对象。 3)    同一个enclosing class对象产生出来的inner class对象访问的是同一个enclosing class对象中的成员。 interface Destination{     String readLabel(); } interface Contents{     int value();     } class Parcel3{     int i1 = 10;     private String s1 = "Parcel3_";     Parcel3(String s){         s1 += s;     }     private class PContents implements Contents{         //可调用enclosing class的成员 (1)         private int i2 = i1;         private String s2 = s1;         PContents(int num){          System.out.println("" + num + ": i2 = " + i2 + ",s2 = " + s2);         }         public int value() { return 1; }     }     public Contents cont(int i){         return new PContents(i);     } } public class ExplicitStatic{         public static void main(String[] args){         Parcel3 p1 = new Parcel3("1");         Contents c1 = p1.cont(1);                 Contents c2 = p1.cont(2);         Parcel3 p2 = new Parcel3("2");         c2 = p2.cont(3);         c2 = p1.cont(4);     } } 结果为: 1: i2 = 10,s2 = Parcel3_1 2: i2 = 10,s2 = Parcel3_1 3: i2 = 10,s2 = Parcel3_2 4: i2 = 10,s2 = Parcel3_1 在(1)在inner class调用了enclosing class的成员。结果表明,同一个enclosing class对象p1产生的inner class对象调用的是同一个enclosing class对象中的成员,如结果中的1、2、4。         2.2  Static inner classes(静态内隐类) 1)    产生Static inner classes对象时,不需要同时存在一个enclosing class对象 2)    只能在Static inner classes对象中访问enclosing class中的静态成员。 interface Contents{     int value();     } class Parcel1{  private static String s1 = "Parcel3_"; private String s11 = “Parcel3_”;     Parcel1(String s){         s1 += s;     } protected static class PContents implements Contents{      //只能访问enclosing class中的s1         String s2 = s1;         //s11不是static成员,不能访问         //String 22 = s11;         PContents(int num){             System.out.println("" + num + ":s2 = " + s2);         }         public int value() { return 1; }     }     public static  Contents cont(int i){         return new PContents(i);     } } public class ExplicitStatic{         public static void main(String[] args){         Parcel1 p1 = new Parcel1("1");         Contents c1 = p1.cont(1);            c1 = Parcel1.cont(2);  //(1)         Parcel1 p2 = new Parcel1("2");         c1 = p2.cont(3);         c1 = Parcel1.cont(4); //(1)     } } 因为内隐类Pcontents class是静态的,所以在(1)处不通过enclosing class对象而是通过静态函数来直接产生其对象。 2.3    无论inner class被嵌套置放的层次有多深,且所有outer class的成员都可 被它访问。 class MNA{     private void f() {}     class A{         private void g() {}         class B{             void h(){                 g();                 f();             }         }     } }      3.    如何产生inner class对象的总结 3.1 non-static内隐类 1)    在enclosing class的non-static函数中可以直接通过new来产生 2)    在enclosing class的static函数或其它的class中,必须同时存在一个enclosing class对象(原因在上面2.1已说明)。 interface Contents{     int value();     } class Parcel1{        protected class PContents implements Contents{         public int value() { return 1; }     }     public Contents cont(){       //在non-static函数中直接通过new来产生PContents class对象         return new PContents();     }     public static void test(String[] args){         Parcel1 p1 = new Parcel1();         //在static函数中通过外部类Parcel1对象来产生         Contents c1 = p1.cont();  //调用函数          c1 = p1.new PContents(); //通过new     } } public class ExplicitStatic{         public static void main(String[] args){         //通过外部类Parcel1对象来产生         Parcel1 p1 = new Parcel1();         Contents c1 = p1.cont();  //调用函数         c1 = p1.new PContents();  //通过new     } } 3.2 static内隐类 1)    除了可用产生non-static内隐类对象的方法来产生之外,也可以不通过已存在一个enclosing class对象来产生。 interface Contents{     int value();     } class Parcel1{        protected static class PContents implements Contents{         public int value() { return 1; }     }     public Contents cont(){       //在non-static函数中直接通过new来产生PContents class对象         return new PContents();     }     public static Contents cont1(){         //在static函数中直接通过new来产生PContents class对象         return new PContents(); //(1)     }     public static void test(String[] args){         Parcel1 p1 = new Parcel1();         //在static函数中通过外部类Parcel1对象来产生         Contents c1 = p1.cont();  //调用函数         c1 = p1.new PContents();  //通过new         //在static函数中直接通过new来产生PContents class对象         c1 = new PContents();  //(1)     } } public class ExplicitStatic{         public static void main(String[] args){         //通过外部类Parcel1对象来产生         Parcel1 p1 = new Parcel1();         Contents c1 = p1.cont();  //调用函数         c1 = p1.new PContents();  //通过new         //直接产生         c1 = Parcel1.cont1();  //(2)     } } 上面的(1)和9(2)中的代码只有在Pcontents class为static时才能通过。(1)不能通过的原因见2.1。 4.    inner class的继承 1)    inner class可被继承。inner class的drived class的 drfault构造函数必须传入一个reference指向outer object,并在构造函数中调用outer class的构造函数。 class WithInner{             class Inner{} } class InheritInner extends WithInner.Inner {             //InheritInner(){}  编译错误             InheritInner(WithInner wi) { wi.super(); } } public class ExplicitStatic{                 public static void main(String[] args){                 WithInner wi = new WithInner();                 InheritInner ii = new InheritInner(wi);             } } 2)    覆写inner class不具备多态特性。 class Egg{     class Yolk{         public Yolk(){             System.out.println("Egg.Yolk()");         }     }     private Yolk y;     public Egg(){         System.out.println("New Egg()");         y = new Yolk(); //(1)     } } class BigEgg extends Egg{     //(2)尝试覆写inner class     class Yolk{         public Yolk(){             System.out.println("BigEgg.Yolk()");         }     } } public class ExplicitStatic{         public static void main(String[] args){         new BigEgg(); //(3)     } } 结果为:     New Egg() Egg.Yolk() 在(2)中我们尝试覆写inner class。当通过(3)产生一个BigEgg时,会调用Egg的构造函数。在Egg的构造函数的(1)处产生的是Egg.Yolk class对象,而不是子类BigEgg.Yolk class对象。 **:如上所示,上述两个inner class是完全独立的个体,各有其专属的命名空间。

阅读全文(1985) | 回复(0) | 编辑 | 精华


发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)
站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 0.094 second(s), page refreshed 144753227 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号