内部类
1)实例内部类
2)静态内部类
3)匿名内部类
4)本地内部类(定义在方法中的内部类)
1 实例内部类
(1)获取实例内部类的对象?
OuterClass.InnerClass innerClass =
outerClass.new InnerClass();
外部类类名.内部类类名 变量 = 外部类对象的引用.new 内部类()
或者采用:
OuterClass.InnerClass innerClass =
new outerClass().new InnerClass();
new outerClass()相当于一个匿名类,即这个外部类没有名字。
(2)在实例内部类当中,不能定义static的属性或者方法
static属于类,不依赖于对象,而内部类相当于外部类的实例成员,要想对内部类进行初始化,必须依赖对象,所以这是矛盾的。 如果非要定义,那么这个属性必须是static final的,被static final 修饰的属性相当于常量,在编译期间就确定了。
(3)实例内部类有没有额外的内存开销?
有,因为实例内部类,包含外部类的this引用
实例内部类至少有两个this。
实例内部类代码举例:
class OuterClass {
public int data1 = 1;
private int data2 = 2;
int data3 = 3;
public static int size = 10;
public OuterClass() {
System.out.println("OuterClass()");
}
//通过外部类方法,访问内部类
public void outerMethod(){
InnerClass inner = new InnerClass();
inner.test();
}
class InnerClass {
public int data4 = 4;
//public static final int size = 10;
public int data1 = 11;
public InnerClass() {
System.out.println("InnerClass()");
}
public void test() {
System.out.println("data1:"+data1);
System.out.println("data1:"+this.data1);
//在内部类中访问外部类成员变量
System.out.println("out::data1:"+
OuterClass.this.data1);
System.out.println("InnerClass::test()");
}
}
}
public static void main(String[] args) {
OuterClass outerClass = new OuterClass();
OuterClass.InnerClass innerClass =
outerClass.new InnerClass();
//以上两行代码可以使用匿名类替换为一行代码
//OuterClass.InnerClass outerClass =
//new OuterClass().new InnerClass();
//通过直接创建内部类对象,访问内部类
innerClass.test();
//通过访问外部类方法,间接访问内部类
outerClass.outerMethod()
}
2 静态内部类
(1)如何拿到静态内部类的对象?
OuterClass2.InnerClass2 innerClass2 =
new OuterClass2.InnerClass2();
外部类类名.内部类类名 变量 = new 外部类名.内部类();
(2)静态内部类当中,不能够访问外部类的非静态数据成员
外部类的非静态数据成员依赖于外部类对象,而静态内部类相当于外部类的一个静态成员,它是不依赖于对象的,所以在静态内部类中,不能够访问外部类的非静态数据成员。如果说,非要进行访问非静态数据成员,那么就要传入外部类对象的引用。 同理,在静态内部类中,也不包含外部类的this。
静态内部类代码实例:
class OuterClass {
public int data1 = 1;
private int data2 = 2;
int data3 = 3;
public static int data5 = 10;
public OuterClass2() {
System.out.println("OuterClass2()");
}
static class InnerClass {
public int data1 = 4;
public static int data5 = 5;
//outerClass2记录传入外部类对象的引用
OuterClass outerClass2;
public InnerClass() {
System.out.println("static::InnerClass2()");
}
//定义一个内部类的有参构造,来接收外部类的对象
public InnerClass(OuterClass o) {
this.outerClass2 = o;
System.out.println("static::
InnerClass2(OuterClass o)");
}
public void test() {
System.out.println("data1:" +
this.outerClass2.data1);
System.out.println(data1);
//若没有传入外部类的对象引用,
//是不能在静态内部类中调用外部类的成员变量的
//System.out.println(data3)
System.out.println("data5:"+data5);
System.out.println("data5:" + OuterClass.data5);
System.out.println("InnerClass2::test()");
}
}
}
public static void main(String[] args) {
//此句是为了向静态内部类中传入外部类对象创建的
OuterClass2 outerClass = new OuterClass2();
OuterClass2.InnerClass2 innerClass2 = new
OuterClass2.InnerClass2(outerClass);
// OuterClass2.InnerClass2 innerClass2 = new
//OuterClass2.InnerClass2();
innerClass2.test();
}
3 匿名内部类
- 本质:其实就是一个子类。
- 接口的实现类或父类的子类只需使用一次,那么即可省去该实现类或子类的定义,匿名内部类主要应用于线程中。
- 使用匿名内部类,就不必再单独定义一个外部实现类了。
匿名内部类代码实例:
class OuterClass{
public int data1 = 10;
public void test() {
System.out.println("OuterClass3::test()");
}
}
public static void main(String[] args) {
new OuterClass(){
//重写test方法
public void test() {
System.out.println("TestDemo1::test()");
}
}.test();//TestDemo1::test()
}
4 本地内部类(局部内部类)
定义在方法内部的类,只能在方法内部使用。
本地内部类,简介链接。