java内部类的使用

话不多说直接走起

1.怎么直接在外部 创建 内部类呢?

复制代码
public class Demo {  
    public static void main(String[] args) {  
        Outer.Inner in=new Outer().new Inner();
        in.show();
    }  
}

class Outer{
    int a=3;
    public class Inner{
        void show() {
            System.out.println("a="+a);
        }
    }
    public void method() {
        new Inner().show();
    }
}
复制代码

要创建 Inner 对象 需要先创建 Outer 对象 因为 Inner类相当于是作为 Outer 类的一个属性存在

然后再创建内部对象。这样写可能比较奇怪,然而它就是需要这样创建的。

 

内部类可以直接使用 外部类的属性或者方法的,不管外部类属性和方法的权限是什么。

 

2.静态内部类的创建

复制代码
public class Demo {  
    public static void main(String[] args) {  
       Outer.Inner in=new Outer.Inner();
       in.show();
    }  
}

class Outer{
    private static int a=3;
    public static class Inner{
        void show() {
            System.out.println("a="+a);
        }
    }
    public void method() {
        new Inner().show();
    }
}
复制代码

此时静态内部类相当于作为外部类的静态属性存在,他是随着外部类的加载而加载的

 

3.非静态内部类不能定义非静态的属性或者方法

复制代码
public class Demo {  
    public static void main(String[] args) {  
       Outer.Inner.show();
    }  
}

class Outer{
    private static int a=3;
    class Inner{
        static void show() {
            System.out.println("a="+a);
        }
    }
    public void method() {
        new Inner().show();
    }
}
复制代码

如上 Inner 类 里面是不能成功定义 show 方法的

这是为什么呢?

因为此时内部类Inner相当于是作为 外部类的 成员属性存在的

假如我们可以定义成功。

只有 创建Outer实例的时候 内部类才会进行加载。

而如果我们直接这样 Outer.Inner.show(); 调用内部类的静态方法的时候

此时因为没有 创建 Outer 对象 所以内部类 Inner 在内存中是不存在的,

更别说是这个类里面的方法了,所以非静态内部类是不能定义静态方法或者属性的。

但是 如果定义的变量是 final 的,这是可以的。

复制代码
public class Demo {  
    public static void main(String[] args) {  
       new Outer().new Inner().show();
    }  
}

class Outer{
    private static int a=3;
    class Inner{
        static final int b=4;
        void show() {
            System.out.println("a="+a);
        }
    }
    public void method() {
        new Inner().show();
    }
}
复制代码

上述 内部类中的变量 b 是可以定义成功的。

这又是为什么呢?

因为我们看到的是 定义了一个常量,然后用常量,打印的时候,打印这个常量,

但是真实是在编译完成之后,里面使用到的常量是直接替换成对应的值得,

所以,以下 对应的地方是直接替换成 数字 4 而不是常量对应的数字 4

void show() {
            System.out.println("a="+4);
        }

我们这样书写,只是为了代码的可读性而已。

 

4.内部类的继承

复制代码
public class Demo {  
    public static void main(String[] args) {  
       Outer outer=new Outer();
       outer.method();
    }  
}
interface Father{
    void show();
}

class Outer{
    private class Inner implements Father{
        static final int b=4;
        public void show() {
            System.out.println("a="+b);
        }
    }
    public void method() {
        Inner aFather= new Inner();
        aFather.show();
    }
}
复制代码

5.内部类继承的简化形式 (匿名内部类)

如果只是用到了 接口中的方法,根本就不需要创建子类对象的引用,只需要引用父类就可以了

复制代码
public class Demo {  
    public static void main(String[] args) {  
       Outer outer=new Outer();
       outer.method();
    }  
}
interface Father{
    void show();
}

class Outer{
    private class Inner implements Father{
        static final int b=4;
        public void show() {
            System.out.println("a="+b);
        }
    }
    public void method() {
        Father aFather= new Inner();
        aFather.show();
    }
}
复制代码

可以进一步简化,内部类的名字已经没有意义了

复制代码
public class Demo {  
    public static void main(String[] args) {  
       Outer outer=new Outer();
       outer.method();
    }  
}
interface Father{
    void show();
}

class Outer{
    public void method() {
        Father aFather= new Father() {
            static final int b=4;
            public void show() {
                System.out.println("a="+b);
            }
        };
        aFather.show();
    }
}
复制代码

这就是匿名内部类的使用

 

如果接口里面的方法只有一个的话,而且只调用一次的话,完全可以进一步简化(可以使用匿名对象)

复制代码
public class Demo {  
    public static void main(String[] args) {  
       Outer outer=new Outer();
       outer.method();
    }  
}
interface Father{
    void show();
}

class Outer{
    public void method() {
        new Father() {
            static final int b=4;
            public void show() {
                System.out.println("a="+b);
            }
        }.show();
    }
}
复制代码

 

 

提醒:

内部类的定义就是为了控制他的访问权限的,一般定义内部类就是为了不让

外部对他进行访问的,所以最好使用 private 来修饰内部类。

 

posted @   escapist  阅读(2867)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示