当前位置:文档之家› 关于JAVA内部类的说明与使用

关于JAVA内部类的说明与使用

关于JAVA内部类的说明与使用1.关于内部类的说明1)在一个类中定义另外一个类,这个类就叫做内部类(inner class) 。

内部类的定义和普通类的定义没什么区别,它可以直接访问和引用它的外部类的所有变量和方法(包括private),就像外部类中的其他非static成员的功能一样。

区别是,外部类只能声明为public和default,而内部类可以声明为private 和protected。

2)当我们建立一个inner class时,其对象就拥有了与外部类对象之间的一种关系,这是通过一个特殊的this reference形成的,当内部类的成员方法中访问某个变量/方法时,如果在该方法和内部类中都没有定义过这个变量,调用就会被传递给内部类中保存的那个外部类对象的引用(OuterClass.this),通过那个外部类对象的引用去调用这个变量。

2.内部类变量访问2.1在main中直接从外部类调用内部类的方法class Outer{private int index = 100;class Inner{private int index = 50;void print(){int index = 30;System.out.println(index); // 30System.out.println(this.index); // 50System.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中显式返回内部类引用class Outer{private int index = 100; [Page]class Inner{private int index = 50;void print(){int index = 30;System.out.println(index); // 30System.out.println(this.index); // 50System.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();}}2.3当main方法在Outer类内部class Outer{private int index = 100; [Page]class Inner{private int index = 50;void print(){int index = 30;System.out.println(index); // 30System.out.println(this.index); // 50System.out.println(Outer.this.index); // 100}}Inner getInner(){return new Inner();//返回一个内部类的引用}public static void main(String[] args){Outer outer = new Outer();Inner inner = outer.getInner(); // 注意此处变化inner.print();}}2.4在main方法中直接产生内部类对象class Test{public static void main(String[] args){Outer outer = new Outer();Outer.Inner inner = outer.new Inner(); // 注意此处变化}}2.5在方法中定义内部类在方法中定义的内部类只能访问方法中的final类型的局部变量,因为用final定义的局部变量相当于是一个常量,它的生命周期超出方法运行的生命周期。

而且方法体中的内部类不能有访问说明符。

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(){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();}}结果: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内部,使之成为内部类。

相关主题