简单的内部类定义形如这样:
class OuterClass{ static class A{//静态内部类 public A( ){ System.out.println("Test$A !"); } } class B{//非静态内部类 public B(){ System.out.println("Test$B !"); } } | |
public void disp( ) { final int a=10; int b; class C //成员函数中的局部内部类 { public C( ) { System.out.println(“in class C a="+a); //System.out.println(b); } } C c=new C( ); } } { public static void main(String args[]) {
B b=new OuterClass( ).new B();
//建立非静态内部类的对象 //注意这个OuterClass().new B();相当于生成一个外部类的对象,然后在利用外部类对象生成内部类对象
OuterClass t=new OuterClass( ); t.disp( ); //通过外部对象调用一个对象方法的形式,新建立了对象C. } }
注意在上面的b在运行时会为0,因为是类属性.
class OuterClass { static class A { } //静态内部类 class B { } //非静态内部类 public void disp( ) { class C{ } //局部内部类 } }
编译后的将产生下面的一些类文件:
OuterClass.class OuterClass$A.class OutClass$B.class OuterClass$1$C.class 记住以下几句话:
1,一个内部类的对象能够访问创建它的外部类对象的所有属性及方法(包括私有部分)。 //可以闭上眼镜,把这个内部类等同于一个类的一个方法,当然就可以访问这个外部类的 //所有方法和属性,私有方法和属性是属于外部类的,当然也就等同于内部类的.
2,对于同一个包中的其它类来说,内部类能够隐藏起来。(将内部类用private修饰即可) //只有在内部类中,才能定义一个为private类型的class,因为这时编译器已经把这个类看作这个类的成员了,但是在一般使用时,就是所谓的”顶级类时”,不能使用private,只能是public 或者是friendly. 如果要是想保证一个类不产生任何的对象,请在构造函数中,把构造函数声明成private. 3, 内部类可定义在方法中,称为局部内部类,但它只能使用方法中的final常量。 // 定义在一个方法内的类,又被成为局部内部类,这个类只能使用在方法中的final常量,注意,这个常量是在一个方法中的,那么能否使用一个类中的常量呢? 当然是可以的,因为类中的常量在在一个方法中是可见的. // 如果把一个类写在了一个if中,比如这样: class A{ int a = 10; if(a!=10){ class B{ B(){ System.out.println(a); } } } } 在编译后会有几个错误呢? 首先那个a没有被定义为final,你有一次上了圈套. 类B同样会被生成出来,只是离开了if域就失效了. 4,内部类可以被定义为抽象类 // abstract 类同样可以在内部类中 5, 非静态内部类不能声明本类的static成员 //只有一个静态的内部类,才可以声明一个static成员, class A{ static class B{
//如果这里不是一个static类,是不可以被声明这个gg方法的. static void gg(){ int a = 100; System.out.println(a); } } }
class aa{ public static void main(String args[]){
A.B hh = new A.B(); hh.gg();
} } 使用内部类可以非常方便的编写事件驱动程序 这个在写事件驱动时,会有很好的解释. 匿名内部类 在某些情况下,我们只需要内部类的一个对象,那么我们就没有必要给内部类命名,没有名字的内部类我们称为匿名内部类 public class A extends Applet { public void init( ) { addMouseListener( new B( ) ); } class B extends MouseAdapter { public void mousePressed(MouseEvent me) { showStatus("Mouse Pressed."); } } }
import java.applet.*; import java.awt.event.*; import java.awt.*; public class AnonymousInnerClassDemo extends Applet { public void init( ) { addMouseListener( new MouseAdapter( ) { public void mousePressed(MouseEvent me) { showStatus("Mouse Pressed"); } } ); } } 下面是一个think in java里的例子 public class Pr{
public Concents cont(){ return new Concents(){
private int i= 11; public int value (){return i;} };//这里是有一个逗号 } } 这个Contents是通过默认的构造函数产生的,匿名类的产生也就是一个新类向上转型到父类的过程. 那么如果一个父类没有一个默认的构造函数,应该什么办呢? 那就只有调用一个super()了. class noname{
Warpping wrap(int x){
return new Warpping(x){
public int value(){
return super.value()*47; } }; } public static void main(String s[]){
noname p = new noname(); Warpping w = p.wrap(10); } }
如果在匿名内部类中用到了外部对象 , 就必须保证这个外部对象是final的 。
public DD dest(final String dest, final float price){
return new DD(){
private int cost; { cost = Math.round(price); if(cost>100) System.out.println("Over budget"); } }; } publc static void main(String []arg){
PP h = new PP(); DD d = h.dest("haha",11.111);
} } |