当生成一个内部类对象的时候,此对象与制造他的外围对象有着一种关系,内部类对象可以访问其外围类对象的所有成员。
如何在外面创建内部类,使用外部类的实例创建内部类,还有一种就是直接使用函数返回内部类的实例
Outer outer=new Outer(); Outer.Inner inner=outer.new Inner();//多层内部类需要一级一级的访问
内部类中返回外部类的引用
public class Outer { void f(){}; class Inner{ public Outer test(){ return Outer.this; } } }
内部类可以使用private修饰,这时候只能外部类访问内部类,这种形式是有意义的,可以让内部类继承一个公共的接口并重写接口中的方法,在外部类由一个函数返回内部类,并且向上转型成他继承的接口。这种情况下任何扩展内部类的行为都是没有价值的,因为只能访问接口中存在的方法,这样对于外面完全隐藏了函数的实现
interface private_test{ void func(); } public class Outer { private class Inner implements private_test{ @Override public void func() { System.out.println("我是私有内部类中的方法"); } } public private_test content(){ return new Inner(); } public static void main(String[] args) { Outer outer=new Outer(); private_test pt=outer.content(); pt.func(); } }
局部内部类
方法中的内部类属于方法本身,外部类不可以直接访问。注意可以在函数中可以返回局部内部类的引用,这时候需要使用它的父类进行向上转型,这种情况下并不意味着函数执行完毕,局部内部类就会死亡。下面的例子很显然,函数返回后函数执行结束,但是局部内部类并没有死亡。
interface LocalInner{ void print(); } public class Outer2 { LocalInner f(){ class Inner implements LocalInner{ @Override public void print(){ System.out.println("我是局部内部类,方法结束,我还没死"); } } return new Inner(); } public static void main(String[] args) throws InterruptedException { Outer2 outer2=new Outer2(); LocalInner f = outer2.f(); TimeUnit.MILLISECONDS.sleep(3000); f.print(); } }
匿名内部类首先要有一个接口,在函数中重新定义内部类,最后返回内部类的引用。
interface Content{ void value(); } public class Outer3 { public Content content(){ return new Content(){ @Override public void value(){ System.out.println("我是匿名内部类"); } }; } public static void main(String[] args) { Content conten= new Outer3().content(); conten.value(); } }
上面实际上是下面代码的简化.
interface Content{ void value(); } public class Outer3 { class Mycontent implements Content{ @Override public void value() { System.out.println("等价的形式"); } } public Content content(){ return new Mycontent(); } public static void main(String[] args) { Content conten= new Outer3().content(); conten.value(); } }
匿名内部类使用外部类的引用的时候必须使用final修饰(JDK8之前),即使现在不需要加了,只是系统自己给加上了。所以在匿名内部类中修改外部类是不允许的。下面这种情况就不行
局部内部类和匿名内部类很相似,唯一的区别就是局部内部类可以有自己的构造函数,所以在需要自己定义构造函数的地方需要使用局部内部类
嵌套类:将内部类声明成static
1)嵌套类的创建,不需要其外部类的对象。
2)不能从嵌套类对象的内部访问非静态的外围类对象。
3)没有this引用
public class Outer4 { static String string="hello"; String string1=""; //不可使用 static class Inner{ Inner(){ System.out.println(string); System.out.println("Inner class 的构造函数"); } } public static void main(String[] args) { Inner inner=new Inner(); //不需要任何外围类的信息 } }
接口中的内部类,这种内部类直接是static的
public interface Outer5 { void howdy(); class test implements Outer5{ @Override public void howdy() { System.out.println("我是接口中的内部类"); } } public static void main(String[] args) { new test().howdy(); //直接可以使用,不需要外围的类 } }
内部类不可以被覆盖:
就是说类A继承类B,类B中有个内部类C,这时候在A中重新定义内部类C,这个内部类是不会被覆盖的。
在向上转型的时候,如果子类重写了父类的方法,这时候,父类调用的时候还是子类中已经重写的方法(public、protected修饰的,并且继承的时候函数的范围只能变大或者相同,不可以变小),由于private是私有的不能被重写,所以这里没有。
重写接口中的方法只能是public abstract修饰,继承接口并重写里面的方法时候修饰符只能是public,另外接口中只能定义常量,public static final,不能定义变量
最后注意所有的类都会生成.class文件,包括内部类。