首页 > 代码库 > Java笔记十八.内部类和匿名类
Java笔记十八.内部类和匿名类
内部类和匿名类
转载请表明出处:http://blog.csdn.net/u012637501(嵌入式_小J的天空)
一、内部类
1.定义
在一个类内部定义类,即为嵌套类(内部类)。有如下几点特点:(1)嵌套类可以直接访问嵌套它的类的成员(变量和方法),包括private成员。但是,嵌套类的成员却不能被嵌套它的类直接访问。(2)内部类使得程序代码更为紧凑,程序更具模块化。
2.内部类实现方法
(1)类中定义和使用一个内部类
在类中直接定义的嵌套类的使用范围,仅限于这个类的内部。内部类的定义和普通类的定义没有什么区别,内部类可以直接访问和引用它的外部类的所有变量和方法,就像外部类中的其他非static成员的功能一样,和外部类不同的是,内部类可以声明为private或protected。
a.内部类被外部类引用
源码:innerClassDemo.java
//外部类 class Outer { String name="我是外部类成员变量"; void outerMethod() //在外部类定义一个成员方法,实现创建一个内部类实例并调用其成员方法 { inner in=new inner(); in.dispaly(); } //内部类 class inner { void display() { System.out.println("Method of inner class print 'name'="+name); } } } /*-------------------------------------------*/ public class innerClassDemo { public static void main(String[] args) { Outer outer = new Outer(); outer.outerMethod(); } }
打印信息:
分析:该源码实现了在外部类Outer中实现一个内部类inner,且在该内部类中定义一个成员方法来使用外部类的Outer的成员name。另外,只能在外部类Outer实例化内部类inner对象,在外部类之外实例化该内部类是不允许的,除非将inner声明为public(后面介绍)。
从内存分布的角度分析,实际上在内部类对象保存了一个对外部类对象的引用(Outer.this),当内部类的成员方法中访问某一变量(方法)时,如果在该方法和内部类中都没有定义过这个变量,调用就会被传递给内部类中保存的哪个外部类对象的引用。通过哪个外部类对象的引用调用这个变量(方法)。
注释:只有放this.变量不存在的情况下,传递给Outer.this.变量。
b.内部类被外部类以外的类引用
内部类可以通过创建对象从外部类之外被调用.
(1)将内部类声明为public;
(2)在外部类以外的类,先创建一个外部类的实例再通过该实例创建内部类的实例
形式:
Outer outer = new Outer();
Outer.Inner inner=outer.new Inner();
源码:InnerClassDemo
//外部类 class Outer { private int number=100; public class Inner { private int number=200; void print(int number) { System.out.println("I am innerClass"+"\n"+"参数number="+number+"\n"+"内部类成员 number="+this.number+"\n"+"外部类成员number="+Outer.this.number); } } } //外部以外的类 public class InnerClassDemo { public static void main(String[] string) { Outer outer = new Outer(); //实例化一个Outer对象 Outer.Inner inner=outer.new Inner(); //实例化一个Inner对象 inner.print(300);//调用外部类的成员方法 } }
打印信息:
分析:观察上面的程序,你会发现三个number变量,其区别为:
number:引用的是print函数的形参;
this.number:引用的是Inner类中的成员变量;
Outer.this.number:引用的外部类Outer中的成员变量。
2.方法中定义的内部类
嵌套类并非智能在类里定义,也可以在几个程序块的范围之内定义内部类。
源码:InnerDemo.java
//外部类 class Outer { private String str="姚明"; public void outerPrint() { int i=10; //内部类 class Inner { void dispaly(final int number) { System.out.println(str); System.out.println(number); //System.out.println(i);//这条语句是错误的,方法中的内部类不能访问方法的非final变量 } } //实例化内部类并调用其成员方法 Inner inner = new Inner(); inner.dispaly(11); } } public class InnerDemo { public static void main(String[] args) { Outer outer = new Outer(); outer.outerPrint(); } }
打印信息:
分析:在方法汇总定义的内部类智能访问方法中的final类型的局部变量(不能访问i),因为用final定义的局部变量就相当于一个常量,它的声明周期查处方法运行的生命周期。
二、匿名内部类
1.匿名类
在学习匿名内部类之前,我们先看下这样一个实例,即实现一个内部类,该内部类继承于另外一个类,表述为在类Outer中定义一个内部类Inner,Inner类又继承了类A。
源码:Outer.java
//类A abstract class A { abstract void display(); } //Outer类,在其main方法中定义一个内部类,该内部类继承于类A public class Outer { //main成员方法 public static void main(String[] args) { //内部类 class Inner extends A { void display() { System.out.println("I am Inner Class."); } } new Outer().callInner(new Inner()); //创建Outer实例并调用其成员方法,方法参数为内部类对象 } //callInner成员方法 public void callInner(A a) { a.display(); } }
打印信息:
分析:由new Outer().callInner(new Inner());可知在Outer.main方法中调用了Outer.callInner方法,传递给callInner方法的参数要求是一个实现了类A中的方法的子类对象。所以,我们在Outer.main方法中定义了一个继承于A类的内部类Inner,该Inner类仅在这里被使用了一次。
对于上面的程序感觉太复杂了,那么我们有什么办法简写它呢?当然。其实,我们在调用callInner方法时,不用实现定义类的Inner,可以在给callInner方法传递参数时,临时创建一个类A的匿名子类的实例对象,代码如下:
源码:Outer.java
//类A abstract class A { abstract void display(); //声明一个抽象类 } //外部类 public class Outer { //main成员方法 public static void main(String[] args) { new Outer().callInner(new A(){ void display() { System.out.println("I am childclass of A,but I have not name -'Inner'"); } }); } //callInner成员方法 public void callInner(A a) { a.display(); } }
打印信息:
分析: 由程序打印的结果,我们可以看出Outer.main方法中调用了Outer.callInner方法,传递给callInner方法的参数要求是一个实现了类A中的方法的子类对象。在上面的程序中就相当于定义了一个类A的子类,但是这个子类是没有类名的,并且接着又创建了这个子类的一个实例对象,这样的类即为匿名类。
2.匿名类的形式
假如我们实现实现了一个类A,那么它的匿名子类的一个实例对象可以这样表示。
形式:new A() { }
作用:产生一个类A的一个匿名子类的实例对象,匿名子类的所有实现代码(包括成员方法和成员变量)都要在那对大括弧间增加即可。
Java笔记十八.内部类和匿名类
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。