内部类

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()方法
   }