内部类
java中有四种内部类,分别为实例内部类、静态内部类、匿名内部类以及本地内部类,这里只介绍前三种。
1.实例内部类
1.如何拿到实例内部类的对象?
外部类名.内部类 in(实例内部类对象名) = 外部类对象.new 内部类名();
2.在实例内部类当中,是否可以定义static的数据成员?
本质上不能,但是可以定义为 static final,必须是在编译时期确定的!
3.内部类可以访问外部类的哪些数据成员?
内部类可以访问外部类的所有数据成员,包括私有的。
4.实例内部类是否有额外的开销?
有额外的开销,包含了外部类的this,实例内部类是外部类的成员,需要通过外部类名.this拿到外部类的对象的引用。
代码示例:
class OuterClass {
public int data1 = 10;
public static int data2 = 20;
//实例内部类InnerClass
class InnerClass {
public int data3 = 100;
public static final int data4 = 200;
public int data1 = 10000;
public void func(){
System.out.println("InnerClass::func()");
System.out.println("data1:"+ this.data1);//访问内部类的data1
System.out.println("data2:"+ data2 );//外部类的data2
System.out.println("data3:"+ this.data3);//内部类的data3
System.out.println("data4:"+ data4);//
//这里若想要访问外部类的data1,需要使用 ->外部类名.this.data1
System.out.println("Outerdata1:"+ OuterClass.this.data1);
}
}
}
public class TestDemo {
public static void main(String[] args) {
OuterClass outerClass = new OuterClass();
//实例内部类的对象 in
//外部类名.内部类 in = 外部类对象.new 内部类名();
OuterClass.InnerClass in = outerClass.new InnerClass();
in.func();
}
}
2.静态内部类
使用 static 关键字来定义静态内部类
1.如何拿到静态内部类的对象?
外部类类名.静态内部类类名 in(静态内部类对象名)= new 外部类类名.内部类();
2.静态内部类能否访问外部类的实例成员?
不能直接访问,可以间接访问,需要拿到外部类的对象(即可以通过 new 外部类().成员 的方式访问 )
代码示例:
class OuterClass2{
public int data1 = 10;
public static int data2 = 20;
//静态内部类InnerClass2
static class InnerClass2{
public int data3 = 200;
public static int data4 = 100;
public int data1 = 300;
OuterClass2 o = null;
public InnerClass2(){
}
public InnerClass2(OuterClass2 out){
this.o = out;
}
public void func(){
System.out.println("InnerClass2::func()");
System.out.println("data3"+ data3);
System.out.println("data4: "+data4);
System.out.println("data1: "+ data1);
System.out.println("data2: "+ data2);
//这种写法错误,因为静态内部类不能直接访问外部类的实例成员
//System.out.println("outdata1:"+ OuterClass2.this.data1);
System.out.println("outdata1"+ o.data1);
}
}
}
public class TestDemo2 {
public static void main(String[] args) {
OuterClass2 outerClass2 = new OuterClass2();
OuterClass2.InnerClass2 innerClass2 = new OuterClass2.InnerClass2(outerClass2);
innerClass2.func();
}
}
3.匿名内部类
定义:若一个局部内部类只被用一次(只用它构建一个对象),就可以不用对其命名了,这种没有名字的类被称为匿名内部类(anonymous inner class)
在线程中用到
使用时直接new 即可
class MyThread {
public void func() {
System.out.println("out::MyThread::func()");
}
}
public static void main3(String[] args) {
//new MyThread();//匿名对象
//匿名内部类-》MyThread的一个子类
new MyThread(){
@Override
public void func() {
//super.func();
System.out.println("inner::MyThread::func()");
}
}.func(); //调用func()方法
}