内部类
概念:
Java中允许把一个类定义在另一个类中,被定义在内部的类,叫做内部类,另一个在外部的类,叫做外部类
分类:
内部类 成员内部类(静态内部类,非静态内部类)和 局部内部类(定义在方法,构造器,代码块中)
成员内部类:
作为类:可以被修饰(abstract,final)继承。类中定义方法、属性、构造器等
作为成员:可以被static修饰作为静态属性,可以调用外部类的结构,可以被权限修饰符修饰 四种权限修饰符.md
重点:
1.如何实例化内部类对象
public class InnerClassTest1 {
public static void main(String[] args) {
//创建静态成员内部类对象(因为静态,通过类名直接调用)
AnimalWorld.Dog dog = new AnimalWorld.Dog();
//创建非静态成员内部类对象(因为非静态,随对象创建创建,所以需先创建外部类对象,再由 外部类对象.new 内部类名())
AnimalWorld animalWorld = new AnimalWorld();
AnimalWorld.Cat cat = animalWorld.new Cat();
}
}
class AnimalWorld{
public static class Dog{}
public class Cat{}
}
2.如何在成员内部类中区分调用外部类的结构 (对于同名,有以下区分,如果非同名,则可省略不写)
class AnimalWorld{
int legs;
public class Cat{
int legs;
public void setLegs(int legs){
//方法参数 直接调用
System.out.println(legs);
//内部类自身属性
System.out.println(this.legs);
//外部类属性AnimalWorld的legs
System.out.println(AnimalWorld.this.legs);
}
}
}
3.开发中的局部内部类使用!!!
public static ITest getNumber(){
// //方式一:不常用
// class UserPutInNumber implements ITest{
// @Override
// public void setNumber() {
// System.out.println("重写");
// }
// }
// return new UserPutInNumber();
//方式二:匿名局部内部类 常用
return new ITest() {
@Override
public void setNumber() {
System.out.println("重写");
}
};
}
}
tips:在局部内部类的方法中,(即在方法中定义了这个类)如果这个内部类的方法中需要调用这个类外部方法里的属性,那么这个属性需要为静态,可以理解为是一种标准
理解上来说,类是一起加载的,所以调用的属性如果不是静态的话是调用不到的(因为不是静态属性,加载还是没有加载好的)
在JDK7必须显式定义,但在JDK8中可以省略
class AnimalWorld{
public void method(){
int b = 10;
class A{
public void test(){
//错误 --- 可以直接使用但不能改变 因为b变为了final
// b = 20;
System.out.println(b);
}
}
}
}
理解上来说,在method方法中的b的作用域为整个method方法(局部变量)AnimalWorld类会生成一个字节码文件,这个b是包含在AnimalWorld类中的字节码文件中的,但是内部类A也会生成一个字节码文件,但是又没有定义局部变量b,虽然语法上是可以直接调用,因为method方法里也包含了内部类A,但是在底层,内部类A用的是b的一个副本,因为是副本所以只能是final的,可以使用,但改变明显是不行的。