• Java内部类(成员内部类、静态内部类、局部内部类、局部内部类)



    在这里插入图片描述

    🐌个人主页: 🐌 叶落闲庭
    💨我的专栏:💨
    c语言
    数据结构
    javaEE
    操作系统
    Redis

    石可破也,而不可夺坚;丹可磨也,而不可夺赤。


    前言: 什么是内部类?

    类的五大成员:
    属性、方法、构造方法、代码块、内部类
    在一个类里面,再定义一个类就是内部类。

    • 内部类表示的事物是外部类的一部分
    • 内部类单独出现没有任何意义
    • 内部类的访问特点:
      • 内部类可以直接访问外部类的成员,包括私有
      • 外部类要访问内部类的成员,必须创建对象
    public class Car {
        private String carName;
        private int carAge;
        private String carColor;
    
        public void show() {
            System.out.println(carName);
            System.out.println(engineName); // 报错
            //创建内部类对象
            Engine engine = new Engine();
            System.out.println(engine.engineName);
        }
    
        class Engine {
            String engineName;
            int engineAge;
    
            public void show() {
                System.out.println(engineName);
                System.out.println(carName);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    一、成员内部类

    1.1 成员内部类的代码如何书写

    • 写在成员位置的,属于外部类的成员。
    • 成员内部类可以被一些修饰符所修饰,比如:private,默认,protected,public,static等
    • 在成员内部类里面,JDK16之前不能定义静态变量,JDK16开始才可以定义静态变量。
    public class Car {
        private String carName;
        private int carAge;
        private String carColor;
    
        public void show() {
        	System.out.println("外部类方法");
        }
    
        private class Engine {	//成员内部类,可添加修饰符
            String engineName;
            int engineAge;
    
            public void show() {
                System.out.println("内部类方法");
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    1.2 如何创建成员内部类的对象

    • 方式一:
      • 在外部类中编写方法,对外提供内部类的对象。
    public class Outer {
        String name;
        class Inner {
    
        }
        public Inner getInstance() {
            return new Inner();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    public class Test {
        public static void main(String[] args) {
            System.out.println(new Outer().getInstance());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 方式二:
      • 直接创建格式:外部类名.内部类名对象名=外部类对象.内部类对象;
    public class Outer {
        String name;
        class Inner {
            
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    public class Test {
        public static void main(String[] args) {
            Outer.Inner oi = new Outer().new Inner();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    1.3 成员内部类如何获取外部类的成员变量

    public class Outer {
        private int a = 10;
        
        class Inner {
            private int a = 20;
    
            public void show() {
                int a = 30;
                System.out.println(a); // 30
                System.out.println(this.a); // 20
                System.out.println(Outer.this.a); // 10
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    public class Test {
        public static void main(String[] args) {
            //创建内部类对象,并调用show方法
            Outer.Inner oi = new Outer().new Inner();
            oi.show();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    代码分析:
    在执行代码时,首先调用main方法,此时在栈内存中添加main方法,并记录Outer.Inner oi的地址,
    方法区中有Test.class的字节码文件,以及其中的main方法、Outer.class和Inner.class的字节码文件以及他们各自的所有成员变量和成员方法
    堆内存中分别记录了外部类对象和内部类对象
    注意:在内部类对象中还隐含了外部类对象的地址。

    在这里插入图片描述


    二、静态内部类

    • 静态内部类也是成员内部类中的一种
    • 静态内部类只能访问外部类中的静态变量和静态方法,如果想要访问非静态的需要创建对象
    • 创建静态内部类对象的格式:外部类名.内部类名 对象名 = new 外部类名.内部类名();
    • 调用非静态方法的格式:先创建对象,用对象调用
    • 调用静态方法的格式:外部类名内部类名.方法名();
    public class Outer {
        int a = 10;
        static int b = 20;
    
        static class Inner {
            public void method1 () {
                //报错
                //System.out.println(a);
            }
            public void method2() {
                System.out.println(b);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    public class Outer {
        int a = 10;
        static int b = 20;
    
        static class Inner {
            public void method1 () {
                System.out.println("非静态方法被调用了");
            }
            public static void method2() {
                System.out.println("静态方法被调用了");
                System.out.println(b);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    public class Test {
        public static void main(String[] args) {
            Outer.Inner oi = new Outer.Inner();
            oi.method1();
            Outer.Inner.method2();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    三、局部内部类

    • 1.将内部类定义在方法里面就叫做局部内部类,类似于方法里面的局部变量。
    • 2.外界是无法直接使用,需要在方法内部创建对象并使用。
    • 3.该类可以直接访问外部类的成员,也可以访问方法内的局部变量。
    public class Outer {
        public void show() {
            final int a = 10;
            //局部内部类
            class Inner {
                String name;
                int age;
                
                public void method1() {
                    System.out.println("局部内部类中的method1方法");
                }
    
                public void method2() {
                    System.out.println("局部内部类中的method2方法");
                }
            }
            //创建局部内部类对象
            Inner i = new Inner();
            System.out.println(i.name);
            System.out.println(i.age);
            i.method1();
            i.method2();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    四、 匿名内部类

    • 1.继承/实现关系
    • 2.方法的重写
    • 3.创建对象

    接口

    public interface Swim {
        public void swim();
    }
    
    • 1
    • 2
    • 3

    抽象类

    public abstract class Animal {
        public abstract void cat();
    }
    
    • 1
    • 2
    • 3

    匿名内部类创建

    public class Test {
        public static void main(String[] args) {
            new Swim() {
    
                @Override
                public void swim() {
                    System.out.println("实现了Swim中的方法");
                }
            };
    
            new Animal() {
    
                @Override
                public void cat() {
                    System.out.println("继承Animal后实现cat方法");
                }
            };
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    在这里插入图片描述


  • 相关阅读:
    问题:anaconda的bin和envs目录莫名奇妙消失!
    【vue项目适配可借助于插件lib-flexible 和postcss-px2rem】
    C++ STL有用?如何调试?
    C++ 封装-构造和析构
    在SpringBoot项目加入冲突动态监测算法
    【毕业设计】基于javaEE+SSH+mysql的医院在线挂号系统设计与实现(毕业论文+程序源码)——医院在线挂号系统
    腾讯员工人均年薪84.7万,马化腾:员工心理健康最重要
    Blazor实战——Known框架增删改查导
    如何删除gitlab上多余的文件夹
    组合数(2)获取C(n,k)组合数列表的QT实现
  • 原文地址:https://blog.csdn.net/qq_64743563/article/details/133230505