(十四)内部类
特点
内部类可以访问外部类的所有作用域。
内部类可以对同一个包的其他类隐藏起来。
链接到外部类
当外部类的对象创建一个内部类对象时,此内部类对象必定会捕捉一个指向外部类对象的引用。
内部类的对象只能在与外部类的对象相关联的情况下才能被创建(内部类是非static时),即必须存在外部类的对象。
在外部类的非静态方法以外的地方,需要用Outer.Inner类指明对象类型。
在外部类的非静态方法内,直接用Inner类指明对象类型。
在外部类的静态方法内和其他类中,必须先实例化一个外部类对象,然后使用Outer.Inner in = out.new Inner();类似的格式才能实例化一个内部类对象。
如果内部类是嵌套类(static类),则不需要对外部类的对象的引用,即不需要先实例化外部类对象。
public class Outer { public static void main(String[] args) { Outer out = new Outer(); //静态方法里必须先实例化外部类对象,才能利用该对象创建对应的内部类对象 Outer.Inner in = out.new Inner(1,2); out.print(); in.print(); } //外部类非静态方法中直接Inner in = new Inner()就可以实例化内部类对象 //外部类非静态方法以外的地方,使用Outer.Inner in = new Outer.Inner(); public void print(){ System.out.println("this is outer class!"); Outer.Inner in = new Outer.Inner(3,4); in.print(); } //返回一个指向内部类对象的引用 public Inner getInner(int i1,int i2){ return new Inner(i1,i2); } private class Inner{ int i1,i2; public Inner(int i1,int i2){ this.i1=i1; this.i2=i2; } public void print(){ System.out.println("this is inner class!"+"i1="+i1+",i2="+i2); } } }
当内部类是private时,在其他类中通过out.new Inner()也无法创建内部类的对象。如下:
public class Test { public static void main(String[] args) { // TODO Auto-generated method stub Outer out = new Outer(); //当Inner是private内部类,则下句无法执行 Outer.Inner in = out.new Inner(2,4); } }
局部类
在方法中定义的类,不能设置为public或private,因为该类对方法以外的范围完全是隐藏的。局部类可以访问它的外部类的作用域。
匿名内部类
只要一个类是抽象的或是一个接口,那么其子类中的方法都可以使用匿名内部类来实现
抽象类的方法实现
abstract class Person { public abstract void eat(); } public class Demo { public static void main(String[] args) { Person p = new Person() { public void eat() { System.out.println("eat something"); } }; p.eat(); } }
在接口上使用匿名内部类
interface Person { public void eat(); } public class Demo { public static void main(String[] args) { Person p = new Person() { public void eat() { System.out.println("eat something"); } }; p.eat(); } }
由上面的例子可以看出,只要一个类是抽象的或是一个接口,那么其子类中的方法都可以使用匿名内部类来实现
最常用的情况就是在多线程的实现上,因为要实现多线程必须继承Thread类或是继承Runnable接口
Thread类的匿名内部类实现
public class Demo { public static void main(String[] args) { Thread t = new Thread() { public void run() { for (int i = 1; i <= 5; i++) { System.out.print(i + " "); } } }; t.start(); } }
Runnable接口的匿名内部类实现
public class Demo { public static void main(String[] args) { Runnable r = new Runnable() { public void run() { for (int i = 1; i <= 5; i++) { System.out.print(i + " "); } } }; Thread t = new Thread(r); t.start(); } }
静态内部类
非静态内部类是附属在外部类对象上的,需要先实例化一个外部类的对象,通过外部类对象才能实例化非静态内部类;而静态内部类可以看做是直接附属在外部类上的,这个静态代表附属体是外部类,而不是外部类实例;
public class Outer { int i; public static void main(String[] args) { Inner in = new Inner(); } public static class Inner{ public Inner(){ System.out.println("Inner has been instanced!"); } } }
联系方式:wuchaodzxx@126.com