广泛意义上的内部类一般来说包括四种:成员内部类,局部内部类,匿名内部类和静态内部类。
成员内部类可以无条件方位外部类的所有成员属性和成员方法,包括private成员和静态成员。
class Circle { private double radius = 0; public static int count =1; public Circle(double radius) { this.radius = radius; } class Draw { //内部类 public void drawSahpe() { System.out.println(radius); //外部类的private成员 System.out.println(count); //外部类的静态成员 } } }值得注意的是,当成员内部类和外部类同名的成员变量或方法时,会发生隐藏现象,即默认情况下访问的是成员内部类的成员。如果需要访问外部类的同名成员,需要以下面这种形式进行访问:
// 外部类.this.成员变量 // 外部类.this.成员方法如果外部类想要访问成员内部类的成员,就必须先创建一个内部类的对象,通过指向这个对象的引用访问。
成员内部类是依附于外部类而存在的,即创建内部类的对象的前提是存在一个外部类的对象。
public class Test { public static void main(String[] args) { //第一种方式: Outter outter = new Outter(); Outter.Inner inner = outter.new Inner(); //必须通过Outter对象来创建 //第二种方式: Outter.Inner inner1 = outter.getInnerInstance(); } } class Outter { private Inner inner = null; public Outter() { } public Inner getInnerInstance() { if(inner == null) inner = new Inner(); return inner; } class Inner { public Inner() { } } }如果成员内部类Inner用private修饰,则只能在外部类的内部访问,如果用public修饰,则任何地方都能访问;如果用protected修饰,则只能在同一个包下或者继承外部类的情况下访问;如果是默认访问权限,则只能在同一个包下访问。
定义在一个方法或者一个作用域里面的类。与成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。
就像一个局部变类一样,不能有public、protected、private、static修饰符。
class People{ public People() { } } class Man{ public Man(){ } public People getWoman(){ class Woman extends People{ //局部内部类 int age =0; } return new Woman(); } }即没有名字的内部类。这个类定义立即消失,且不能重复使用,通常用来简化代码。
使用匿名内部类的前提条件是:必须继承一个父类或实现一个接口,最多继承一个父类或实现一个接口。
使用规则:
匿名内部类不能是抽象类,因为系统在创建匿名内部类时,会立即创建匿名内部类的对象。因此不允许将匿名内部类定义成抽象类。匿名内部类不能定义构造器。因为匿名内部类没有类名,所以无法定义构造器。但是匿名内部类可以定义初始化块,通过实例初始化块来完成构造器需要完成的事情。在上述代码中的Child类只使用一次的情况下,将其编写成内部类可以简化代码。
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(); } }只要一个类是抽象的,那么其子类中的的方法都可以使用匿名内部类来实现。
静态内部类与成员内部类相比,多了一个static,即不需要依赖于外部类。此外,它不能使用外部类的非静态成员变量或者方法。
public class Test { public static void main(String[] args) { Outter.Inner inner = new Outter.Inner(); } } class Outter { public Outter() { } static class Inner { public Inner() { } } }