一、匿名内部类
- 匿名内部类是没有访问修饰符的。
- new 匿名内部类,这个类首先是要存在的(有对应的接口定义),否则就会出现编译错误。
- 匿名内部类访问外部类的局部变量,该变量必须是 final 类型的,因为匿名内部类是以拷贝的形式进行初始化,需要使用 final 变量,保证数据一致性。
- 匿名内部类没有名字,也就没有构造函数。
示例:
Interface InnerClass {
int getNum();
}
public class AnonymInnerClass {
public InnerClass getInnerClass(final int num, String str) {
return new InnerClass() {
int number = num + 3;
public int getNum() {
reurn number;
}
};
}
public static void main(String[] args) {
AnonymInnerClass anonymInnerClass = new AnonymInnerClass();
InnerClass inner = anonumInnerClass.getInnerClass(4, "test");
System.out.println(inner.getNum());
}
}
// 输出结果:7
二、成员内部类
1. 非静态内部类有着一个指向外部类对象的引用。
2. 普通内部类对象的创建:
Outer o = new Outer();
Outer.Inner in = o.new Inner();
3. 当内部类的属性与外部类同名时,会覆盖外部类的同名属性。
4. 如果要生成外部类对象的引用,可以使用 OuterClassName.this ,这样就可以产生一个正确的外部类引用了。
5. 内部类是一个编译时概念,一旦编译成功,它就与外围类属于两个完全不同的类(联系:内部类含有外部类对象的引用)。
6. 成员内部类可以无限制的访问外部类的属性和方法(包括 private),但是外部类要访问内部类的成员属性和方法,则需要通过内部类实例来访问。
7. 成员内部类的两个注意点:
1) 成员内部类不能存在任何 static 类型的变量和方法。
2) 成员内部类是依附与外围类的,只有先创建了外部类,才能够创建内部类。
示例:
public class OutClass {
private String name;
private int age;
class Inner { // 内部类可以访问外部类所有属性和方法
public void printName() {
System.out.println(name);
}
public void setName(String str) {
OutClass.this.name = str;
System.out.println(OutClass.this.name);
}
private String name = "inner name";
public void print(){
System.out.println(name);
System.out.println(OutClass.this.name);
}
}
// 外部类调用内部类的方法
public void outInvokeInner(){
Inner in = new Inner();
System.out.println("outer invoke inner");
in.print();
}
public static void main(String[] args) {
OutClass out = new OutClass();
OutClass.Inner in = out.new Inner();
in.printName();
in.setName("Hello");
in.print();
out.outInvokeInner(); // 外部类调用内部类方法
}
}
/**
* 输出:
* inner name
* Hello
* inner name
* Hello
* Outer invoke inner
* inner name
* Hello
*/