把一个类放在一个类内部定义,这个定义在其他类内部的类就被称为内部类。
1. 内部类作用如下:
1)内部类提供了更好的封装,把内部类应藏在外部类之内,不允许同一个包内的其他类访问该类。假设该类在脱离了某个类之外没有任何意义,可以将该类定义在依赖的类里。
2)内部类成员可以直接访问外部的私有数据,因为内部类被当成外部类的成员,同一个类的成员之间可以互相访问。
3)匿名内部类适合用于创建那些仅需要一次使用的类。
2. 非静态内部类:
先创建外部类对象,再通过外部类对象创建内部类。Java不允许在非静态内部类重定义静态成员,静态方法,也不能有静态初始化块。
public class OutClass { private String a; private static String name; public void f(){} public static void fn(){} class InClass{ private String b; public InClass(){ b=a; b=name; f(); fn(); } } public static void main(String[] args) { OutClass.InClass inClass = new OutClass().new InClass(); } }
3. 静态内部类:
如果用static来修饰一个内部类,它就属于这个外部类本身,而不属于某个外部类实例。根据静态成员不能访问非静态成员原则,静态内部类也不能访问外部类的非静态成员。
public class OutClass {
private int a;
private static String name;
public OutClass(){}
public void f() {}
public static void fn(){}
public static class InClass{
private int b;
private static String c;
public InClass(){
//b=a; //不能访问外部类的非静态变量
c=name;
//f(); //不能使用外部类的非静态方法
fn();
}
}
public static void main(String[] args) {
OutClass.InClass inClass =new InClass();
}
}
4.接口内部类:
接口内部类默认使用public staic修饰符。
5. 局部内部类:
如果把一个内部类放在方法里定义,这个类就是一个局部内部类。对于局部成员,使用static修饰毫无意义,所以局部内部类不能用static修饰
public class Test { public static void main(String[] args) { abstract class InnerBase{ int a; public abstract void fn(); } class Inner extends InnerBase{ public void fn(){} } InnerBase inner = new Inner(); } }
6.匿名内部类
匿名类适合创建那种只需要一次使用的类。你明年内部类必须集成一个父类或实现一个接口。必须实现父类或接口的所有抽象方法。
如果匿名内部类想要访问外部类的变量,则必须使用final修饰符来修饰外部类的局部变量。
public class Test { interface Product{ public String getName(); } public abstract class Pro{ public abstract void printName(); } public static void main(String[] args) { System.out.println(new Product(){ { System.out.println("实现接口的匿名内部类初始化!"); } public String getName(){ return "computer"; } }.getName()); final String nameString = "Keyboard"; new Test().new Pro(){ { System.out.println("继承类的匿名内部类初始化!"); } public void printName(){ System.out.println(nameString);; } }.printName(); } }
7.闭包和回调:
闭包是一种能被调用的对象,它保存了创建它的作用域信息。非静态内部类不仅记录了外部类的详细信息,还保留了一个创建非静态内部类对象引用,还可直接调用外部类的private成员,因此可以把非静态内部类当成面向对象领域的闭包。
以下代码为实际应用:
public class test { public abstract class Teachable{ abstract void work(); } public class Programmer{ public void work(){ System.out.println("coding"); } } public class TeachableProgrammer extends Programmer{ private void teach() { System.out.println("teaching"); } private class Closure extends Teachable{ @Override public void work() { teach(); } } public Teachable getCallBackReference(){ return new Closure(); } } public static void main(String[] args) { TeachableProgrammer tProgrammer = new test().new TeachableProgrammer(); tProgrammer.work(); tProgrammer.getCallBackReference().work(); } }
以上内容来自学习《疯狂JAVA讲义》