内部类
内部类就是在一个类的内部定义一个类。
选择:
对外不想要这个类被访问,根据作用范围来选择内部类,类的内部--静态内部类,某个方法---匿名内部类
对内,想要访问某些内部数据,比如私有属性
成员内部类
可以访问外部成员的属性,方法,构造器
public class Animal{ private int age; public String name; public int x = 9; public void test(){ // System.out.println(sex); 外部类不能调用内部类属性,方法 //// 外部类调用内部类 new Animal().new Cat().getAge(); } // 成员内部类 class Cat{ // 内部成员属性,外部不能调用 public String sex; int x = 8; public void getAge(){ int x = 7; //可以调用外部类的私有属性,和成员属性 System.out.println(age); String catName = name; System.out.println(x); System.out.println(this.x); System.out.println(Animal.this.x); test(); //调用外部类的成员方法 } } public static void main(String[] args) { // 通过外部类调用内部类 Cat cat = new Animal().new Cat(); cat.getAge(); // 7,8,9 } }
静态内部类
只能调用外部类中的静态内容
public class Animal{ private static int age; public String name; public void test(){ // System.out.println(sex); 外部类不能调用内部类属性,方法 // 外部类调用内部类 new Animal.Cat().getAge(); } // 静态 成员内部类 static class Cat{ public void getAge(){ // 不能添加修饰符 String sex; // test(); 不能调用外部类的非静态方法和属性 //String catName = name; //只能调用外部类的静态的 私有属性,和成员属性 System.out.println(age); } } public static void main(String[] args) { // 通过外部类调用静态内部类 new Animal.Cat().getAge(); } }
局部内部类
局部内部类放在方法、代码块、构造器等执行体中,
局部内部类只在当前方法中有效
不能定义static成员。
局部内部类只能访问当前方法中的final类型的参数和变量
外部类不能访问局部内部类,只能在方法体中访问局部内部类,且访问必须在内部类定义之后。
public class Student{ private int age; public String name = "aa"; public void test(){ final int a =10; String b = null; b ="hahha"; String c = null; //System.out.println(sex); //外部类不能调用内部类属性,方法 // 局部内部类 不能有修饰符 class Cat{ public String sex; public void getCat(final int d){ // 访问外部类中的成员 System.out.println(name); // 匿名内部类调用的方法必须是fianl修饰的 System.out.println(a); //System.out.println(b); b修改引用地址,不是final类型 System.out.println(c);// c 没有进行修改 System.out.println(d);// c 没有进行修改 } } //外部类不能访问局部内部类,只能在方法体中访问局部内部类,且访问必须在内部类定义之后。 Cat cat = new Cat(); cat.getCat(); } public static void main(String[] args) { //外部不能直接调用内部类,只能在方法中调用,通过方法间接调用 Student s = new Student(); s.test(); } }
匿名内部类
1、使用匿名内部类时,我们必须是继承一个类或者实现一个接口,但是两者不可兼得,同时也只能继承一个类或者实现一个接口。
2、匿名内部类中是不能定义构造函数的。
3、匿名内部类中不能存在任何的静态成员变量和静态方法。
4、匿名内部类为局部内部类,所以局部内部类的所有限制同样对匿名内部类生效。
5、匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法。
public class Animal{ public void eat(){} } public class Dog extends Animal{ @Override public void eat(){} } public class Test { public static void main(String[] args) { // Dog test2 = new Dog(); 一般我们这么定义但是如果这个方法我们只使用一次,就没必要创建对象了 // test2.eat(); //匿名内部类 Animal a = new Animal(){ @Override public void eat(){ System.out.println("11111"); } public void drink(){ System.out.println("222"); } }; a.drink(); a.eat(); } }
补充
为什么匿名/局部内部类中不能有静态的方法、属性?
因为静态的方法属性会在外部类加载时就加载。这样直接”外部类名.“就访问了,但是这些静态方法是属于内部类的,这个时候有可能内部类还没有创建,所以在语法上不符合基本逻辑。