[计院]Java内部类

215 阅读3分钟
详情参考这篇文章Java内部类详解
内部类就是,在一个类里放了另一个类。
为什么要放一个类进另一个类呢?
最根本的原因:为了完善Java缺少的“多根继承”的概念。
内部类有四种:
成员内部类
局部内部类
匿名内部类
静态内部类

一、成员内部类

class outSide{
    private int number = 1;
    
    class innerSide{
        private int number= 2;
        public void method(){
            int number = 3;
            System.out.print(number);
            System.out.print(this.number);
            System.out.print(outSider.this.number);
    }
    
}
//创建实例
public class Test{
    public static void main(String[] args){
        outSide out = new outSide();
        outSide.innerSide inner = out.new innerSide();   //这是成员内部类生成实例的方式
        inner.method(); // 输出 3 2 1
    }
}
特点:1.内部类 可以访问 外部类 的所有属性和方法 (实现原理:在内部类中生成一个引用外部类的this指针)。
当发生内外属性重名时,如果不指名是谁家的,将屏蔽外部属性。
2.外部类 若要访问 内部类的属性和方法,需要生成一个内部类的实例对象才行。
3.没有先生成外部类的实例对象的话,无法使用其中的内部类(原因:因为内部类构造器需要传入指向外部类实例对象的this指针)。
4.内部类好比外部类内的一个方法,可以用public、private、protected、default 和static 等修饰符修饰。
5.内部类 和 外部类 可分别继承不同的父类。

二、局部内部类

内部类放在在方法或一个作用域里。
class outSide{
    private int number = 1;
    
    public void method{
        int number = 2;
        class interSide{
             public void print1(){
                 System.out.println(number);
        }
        
        interSide inter = new interSide();
        inter.print1();  
    }
}
public class Test{
    public static void main(String[] args){
        outSide out = new outSide();
        out.method(); //输出2
    }
}       
特点:1.局部内部类有如局部变量,不能被public、private、protected、default 和 static 修饰。
2.局部内部类的方法只能访问局部final变量。
(因为传进内部类方法的参数生命周期可能比方法的生命周期短,为了解决这个问题,Java对可确定的参数采用拷贝,对不确定的参数采用内部类构造器初始化的方法来解决。
在这种解决办法下,如果对拷贝后的值进行修改,显然违背数据一致,因此将传进的参数要求为final,复制得到的也为final类型,都不可以改变)

三、匿名内部类

某个小小的类只在很固定的地方,如形式参数那边使用,就懒得规规矩矩写出一个类然后new对象,再把对象传进参数了。
现在就在固定的那个地方把类当场给写了,顺便new一个没名字的对象过去,连取名字都省了,nice。
interface example{
    void realizeIt();
}
class oneClass{
    public void method(example exam){
        exam.realizeIt();
    }
}
public class Test{
    public static void main(String [] args){
        oneClass one = new oneClass();
        one.method(new example(){
            @Override
            public void realizeIt(){
                System.out.println("use only once");
            }
        });
    }
}
特点:1.匿名内部类 和 局部内部类 一样,不能被public、private、protected、default 和 static 修饰。
2.匿名内部类 是 唯一 没有 构造器 的类,只能用其超类的构造器。(问题来了,上面代码用的构造方法名字是接口名诶,实际是转换成了Object类的构造方法)。
3.匿名内部类也只能访问局部final变量。

四、静态内部类

和成员内部类表面的差别就在于,静态内部类有static修饰符。
class outSide{
    private int no = 1;
    private static int yes = 2;
    
    static class innerSide{
        private int number = 3;
        
        public void method(){
            System.out.println(outSide.this.no);  // 编译失败,属性 no 不是 static 修饰的静态变量。
            System.out.println(yes); //编译通过,输出 2
        }
    }
}
public class Test{
    public static void main(String[] args){
        outSide.innerSide inner = new innerSide();
        //or   /* outSide.innerSide inner = new Outside.innerSide(); */
        inner.method(); // 输出 2 
    }
}
特点:1.静态内部类 不能 访问 外部内部类 的非静态成员变量和方法。
          2.静态内部类的使用 不依赖于 外部类实例对象。