简单来说将一个类定义到另一个类里面,里面那个类就称为是内部类
内部类的访问特点:
内部类可以直接访问外部类中的成员,包括私有成员。外部类要访问内部类中的成员必须要建立内部类的对象才能访问。
内部类的用处:
内部类一般用于类的设计。分析事物时,发现该事物描述中还有事物,而且这个事物还在访问被描述事物的内容。这个时候,这个事物中的事物就定义成内部类来描述。
内部类的修饰符:
由于内部类被定义在成员位置,所以内部类可以被成员修饰符修饰。
内部类可以在其他类中直接访问,例:
class Outer{ private int num=3; class Inner{ void show(){ System.out.println("show run"+num); } } public void method(){ Inner in = new Inner(); in.show(); } } class InnerDemo{ public static void main(String[]args){ //直接访问外部类中的内部类中的成员。 Outer.Inner in =new Outer().new Inner(); in.show(); } }如果内部类是静态的,其实相当于一个外部类。可以直接用外部类的对象调用内部类类名使用,例:
class Outer{ private static int num=3; static class Inner{ void show(){ System.out.println("show run"+num); } } public static void method(){ Inner in = new Inner(); in.show(); } } class InnerDemo{ public static void main(String[]args){ Outer.Inner in =new Outer.Inner(); in.show(); } }如果内部类中定义了静态的成员,该内部类也必须定义成静态的否则会编译失败,例:
class Outer{ private static int num=3; class Inner{ void show(){ System.out.println("show run"+num); } public static void function(){ System.out.println("function 运行了"); } } public static void method(){ Inner in = new Inner(); in.show(); } } class InnerDemo{ public static void main(String[]args){ Outer.Inner.function(); } }结果为: Compiling InnerDemo.java…… InnerDemo.java:63: 错误: 内部类Outer.Inner中的静态声明非法 public static void function(){ ^ 修饰符 ‘static’ 仅允许在常量变量声明中使用 InnerDemo.java:68: 错误: 无法从静态上下文中引用非静态 变量 this Inner in = new Inner(); ^ 2 个错误 [Finished in 0.6s]
为什么内部类可以直接访问外部类的成员:
因为内部类被定义在外部类的成员位置,该内部类就持有了外部类的引用(外部类名.this)
内部类可以放在局部位置上 ,例:
public class InnerDemo2{ public static void main(String[]args){ new Outer().method(); } } class Outer{ int num=3; void method(){ class Inner{ void show(){ System.out.println("show......"+num); } } Inner in = new Inner(); in.show(); } }当内部类处于局部位置时,该内部类只能访问局部中被final修饰的局部变量。
public class InnerDemo2{ public static void main(String[]args){ Outer out = new Outer(); Object obj = out.method(); } } class Outer{ final int num=3; Object method(){ int x = 9; class Inner{ void show(){ System.out.println("show......"+x); } } Object in = new Inner(); // in.show(); return in; } }匿名内部类:
匿名内部类其实就是内部类的简写格式,是一个匿名 的子类对象,可以直接在类的结束部分加点调用。 简写的前提:内部类必须实现或者继承一个外部类或者接口
public class InnerDemo3{ public static void main(String []args){ new Outer().method(); } } abstract class Demo{ abstract void show(); } class Outer{ int num=4; public void method(){ new Demo(){ void show(){ System.out.println("show......"+num); } }.show(); } }匿名内部类的使用场景:
当函数参数是接口类型时,且接口中的方法不超过三个,这个时候就可以用匿名内部类作为实际参数进行传递。
使用匿名内部类的注意事项:
当在创建内部类对象的时候可以调用子类特有的方法,当创建对象的父类引用类型时,就不能引用子类特有的方法了,因为对象已经向上进行了转型。 例:1.在创建时调用
public class InnerDemo5{ public static void main(String[]args){ new Outer().method(); } } class Outer{ void method(){ new Object(){ public void show(){ System.out.println("show run"); } }.show(); } }结果如下:
Compiling InnerDemo5.java…… ——Output—— show run [Finished in 0.6s] 2.创建子类对象的父类引用类型时,调用子类特有的方法
public class InnerDemo5{ public static void main(String[]args){ new Outer().method(); } } class Outer{ void method(){ Object obj = new Object(){ public void show(){ System.out.println("show run"); } }; obj.show(); } }运行结果如下:
Compiling InnerDemo5.java…… InnerDemo5.java:14: 错误: 找不到符号 obj.show(); ^ 符号: 方法 show() 位置: 类型为Object的变量 obj 1 个错误 ——Output—— [Finished in 0.6s]