【java】内部类
内部类的使用场景:
- 将内部类隐藏在外部类之内,不允许同一个包中的其他类直接访问该类。
- 内部类成员可以直接访问外部类的私有数据,内部类被当作外部类成员,但外部类不能访问内部类的实现细节。
非静态内部类
非静态内部类中不能拥有静态成员。
public class Cow{
private double weight;
private static int size = 20;
public Cow(){}
public Cow(double weight){
this.weight = weight;
}
private class CowLeg{
private double length = 32.3;
private String color = "niuniu";
public CowLeg(){}
public CowLeg(double length, String color){
this.length = length;
this.color = color;
}
public void info(){
System.out.println("当前牛腿颜色是:" + color + "高:" + length);
//非静态内部类中可以访问外部类的private实例变量
System.out.println("当前牛腿重量:" + weight);
System.out.println("当前牛的size:" + size);
}
}
public void test(){
CowLeg cl = new CowLeg();
cl.info();
}
public static void main(String[] args) {
Cow cow = new Cow(378.9);
cow.test();
}
}
非静态内部类对象中,保存了一个它所寄生的外部类对象的引用,即:非静态内部类实例必须寄生在外部类实例中,这也是非静态内部类可以调用外部类的private成员的原因。
非静态内部类中的方法访问某个变量时的顺序为:
- 优先看是否存在该名字的局部变量
- 其次在内部类中查找是否存在改名字的成员变量
- 外部类中查找是否存在该名字的成员变量
- 如果仍然不存在,系统将出现编译错误
在内部类中,可以使用this、外部类类名.this来区分内外部类中同名变量。
public class DiscernVariable{
private String prop = "外部类的实例变量";
private class InClass{
private String prop = "内部类的实例变量";
public void info(){
String prop = "局部变量";
System.out.println("外部类的实例变量值:" + DiscernVariable.this.prop);
System.out.println("内部类的实例变量值:" + this.prop);
System.out.println("局部变量" + prop);
}
}
public void test(){
InClass in = new InClass();
in.info();
}
public static void main(String[] args){
new DiscernVariable.test();
}
}
非静态内部类的成员可以访问外部类的private成员,但外部类不能访问内部类的成员。如果必须访问,则可以通过new 一个内部类实例对象来实现。
静态内部类
如果使用static来修饰一个内部类,则这个内部类就属于这个外部类本身,而不属于外部类的某个对象,这样的类叫静态内部类。
根据静态成员不能访问非静态成员的规则,静态内部类不能访问外部类的实例成员,只能访问外部类的类成员。