江西广告网

标题: Java中的内部类问题 [打印本页]

作者: 一丰    时间: 2009-2-17 10:58
标题: Java中的内部类问题
.关于内部类的说明 1)在一个类中定义另外一个类,这个类就叫做内部类(inner class) 。内部类的定义和普通类的定义没什么区别,它可以直接访问和引用它的外部类的所有变量和方法(包括private),就像外部类中的其他非static成员的功能一样。区别是,外部类只能声明为public和default,而内部类可以声明为private和protected。 2)当我们建立一个inner class时,其对象就拥有了与外部类对象之间的一种关系,这是通过一个特殊的this reference形成的,当内部类的成员方法中访问某个变量/方法时,如果在该方法和内部类中都没有定义过这个变量,调用就会被传递给内部类中保存的那个外部类对象的引用(OuterClass.this),通过那个外部类对象的引用去调用这个变量。 2.内部类变量访问 2.1在main中直接从外部类调用内部类的方法 package org.zj.sample; class Outer { private int index = 100; class Inner { private int index = 50; void print() { int index = 30; System.out.println(index); // 30 System.out.println(this.index); // 50 System.out.println(Outer.this.index); // 100 } } void print() { Inner inner = new Inner();//得到内部类的引用 inner.print(); } } class Test { public static void main(String[] args) { Outer outer = new Outer(); outer.print(); } } 该示例程序列出了重名成员变量分布的3种情况。 访问内部类方法中的变量: System.out.println(index); 访问内部类中的成员变量: System.out.println(this.index); 访问所在外部类的成员变量: System.out.println(Outer.this.index); 2.2在main中显式返回内部类引用 package org.zj.example; class Outer { private int index = 100; [Page] class Inner { private int index = 50; void print() { int index = 30; System.out.println(index); // 30 System.out.println(this.index); // 50 System.out.println(Outer.this.index); // 100 } } Inner getInner() { return new Inner();//返回一个内部类的引用 } } class Test { public static void main(String[] args) { Outer outer = new Outer(); Outer.Inner inner = outer.getInner(); inner.print(); } } 2.3当main方法在Outer类内部 package org.zj.sample1; class Outer { private int index = 100; class Inner { private int index = 50; void print() { int index = 30; System.out.println(index); // 30 System.out.println(this.index); // 50 System.out.println(Outer.this.index); // 100 } [1] [2] [3] } Inner getInner() { return new Inner(); } public static void main(String[] args) { [Page] Outer outer = new Outer(); Inner inner = outer.getInner(); // 注意此处变化 inner.print(); } } 2.4在main方法中直接产生内部类对象 package org.zj.sample2; class Outer { private int index = 100; class Inner { private int index = 50; void print() { int index = 30; System.out.println(index); // 30 System.out.println(this.index); // 50 System.out.println(Outer.this.index); // 100 } } } class Test { public static void main(String[] args) { Outer outer = new Outer(); Outer.Inner inner = outer.new Inner(); // 注意此处变化 inner.print(); } } 2.5在方法中定义内部类 在方法中定义的内部类只能访问方法中的final类型的局部变量,因为用final定义的局部变量相当于是一个常量,它的生命周期超出方法运行的生命周期。而且方法体中的内部类不能有访问说明符。 package org.zj.sample; class InOut { String str=new String(\"Between\"); public void amethod(final int aArgs){ class Inner{ public Inner(){ System.out.println(\"This is Inner.\");//此句可看出它与匿名内部类用法的不同。 } public void sayHello(){ [Page] System.out.println(str); System.out.println(aArgs); } } Inner inner=new Inner();//此句必须放在定义类Inner的后面 inner.sayHello(); } public static void main(String[] args){ InOut inOut=new InOut(); inOut.amethod(33); } } 在方法体中使用内部类可以使用一个已命名的构造子,或重载构造子。而匿名内部类只能用于实例初始化。 3.内部类的继承 当一个类继承自一个内部类时,缺省的构造器不可用。必须使用如下语法: enclosingClassReference.super();(见下例绿色部分) package org.zj.sample; class WithInner{ class Inner{ public void sayHello(){ System.out.println(\"Hello.\"); } } } public class InheritInner extends WithInner.Inner { InheritInner(WithInner wi){ wi.super(); } public static void main(String[] args) { WithInner wi=new WithInner(); InheritInner ii=new InheritInner(wi); ii.sayHello(); 上一页 [1] [2] [3] } } 结果: Hello. 4.匿名内部类 未使用匿名内部类的情况:这里单独写了一个内部类Inner。 package org.zj.example; abstract class A{ abstract public void sayHello(); } class Outer { public static void main(String[] args){ class Inner extends A{ public void sayHello(){ [Page] System.out.println(\"Hello!\"); } } new Outer().callInner(new Inner()); } public void callInner(A a){ a.sayHello(); } } 使用匿名内部类的情况:直接在new A()中给出Inner的定义。 package org.zj.example; abstract class A{ abstract public void sayHello(); } class Outer { public static void main(String[] args){ new Outer().callInner(new A(){ public void sayHello(){ System.out.println(\"Hello!\"); } }); } public void callInner(A a){ a.sayHello(); } } 5.内部类的2种特殊用法 一个类从另一个类派生出来,又要实现一个接口。但在接口中定义的方法与父类中定义的方法的意义不同,则可以利用内部类来解决这个问题。 package org.zj.sample; interface Machine { void run(); } class Person { void run() { System.out.println(\"run\"); } } class Robot extends Person { private class MachineHeart implements Machine { public void run() { System.out.println(\"heart run\"); } } Machine getMachine() { return new MachineHeart(); } [Page] } class Test { public static void main(String[] args) { Robot robot = new Robot(); Machine m = robot.getMachine(); m.run(); robot.run(); } } 在Robot类内部使用内部类MachineHeart来实现接口Machine的run方法。同时Robot类又继承了父类Person的run方法。如果不使用内部类MachineHeart而使Robot直接实现接口Machine,则该如何调用父类的run方法? 利用内部类可解决c 中多重继承所解决的问题 package org.zj.example; class A { void fn1() { System.out.println(\"It’s fn1.\"); } } abstract class B { abstract void fn2(); } class C extends A { B getB() { return new B() { public void fn2() { System.out.println(\"It’s fn2.\"); } }; } } class Test { public static void main(String[] args) { C c = new C(); c.fn1(); c.getB().fn2(); } } 类C既要继承类A又要继承类B,则可将类B的定义放入类C内部,使之成为内部类。 6.我们为什么使用内部类 这是对上一章节两种用法的总结,可结合上一章节的两个实例分析。 1) 当我们需要在某一情形下实现一个接口,而在另一情形下又不需要实现这个接口时,我们可以使用内部类来解决这一问题。让内部类来实现这个接口。 2) 内部类有效的解决了多重继承的问题。 上一页 [1] [2] [3]




欢迎光临 江西广告网 (http://bbs.jxadw.com/) Powered by Discuz! X3.2