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


🐌个人主页: 🐌 叶落闲庭

💨我的专栏:💨
c语言
数据结构
javaEE
操作系统
Redis

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


内部类

  • [前言: 什么是内部类?](#前言: 什么是内部类?)
  • 一、成员内部类
    • [1.1 成员内部类的代码如何书写](#1.1 成员内部类的代码如何书写)
    • [1.2 如何创建成员内部类的对象](#1.2 如何创建成员内部类的对象)
    • [1.3 成员内部类如何获取外部类的成员变量](#1.3 成员内部类如何获取外部类的成员变量)
  • 二、静态内部类
  • 三、局部内部类
  • [四、 匿名内部类](#四、 匿名内部类)

前言: 什么是内部类?

类的五大成员:

属性、方法、构造方法、代码块、内部类

在一个类里面,再定义一个类就是内部类。

  • 内部类表示的事物是外部类的一部分
  • 内部类单独出现没有任何意义
  • 内部类的访问特点:
    • 内部类可以直接访问外部类的成员,包括私有
    • 外部类要访问内部类的成员,必须创建对象
java 复制代码
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.1 成员内部类的代码如何书写

  • 写在成员位置的,属于外部类的成员。
  • 成员内部类可以被一些修饰符所修饰,比如:private,默认,protected,public,static等
  • 在成员内部类里面,JDK16之前不能定义静态变量,JDK16开始才可以定义静态变量。
java 复制代码
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 如何创建成员内部类的对象

  • 方式一:
    • 在外部类中编写方法,对外提供内部类的对象。
java 复制代码
public class Outer {
    String name;
    class Inner {

    }
    public Inner getInstance() {
        return new Inner();
    }
}
java 复制代码
public class Test {
    public static void main(String[] args) {
        System.out.println(new Outer().getInstance());
    }
}
  • 方式二:
    • 直接创建格式:外部类名.内部类名对象名=外部类对象.内部类对象;
java 复制代码
public class Outer {
    String name;
    class Inner {
        
    }
}
java 复制代码
public class Test {
    public static void main(String[] args) {
        Outer.Inner oi = new Outer().new Inner();
    }
}

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

java 复制代码
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
        }
    }
}
java 复制代码
public class Test {
    public static void main(String[] args) {
        //创建内部类对象,并调用show方法
        Outer.Inner oi = new Outer().new Inner();
        oi.show();
    }
}

代码分析:

在执行代码时,首先调用main方法,此时在栈内存 中添加main方法,并记录Outer.Inner oi的地址,

方法区 中有Test.class的字节码文件,以及其中的main方法、Outer.class和Inner.class的字节码文件以及他们各自的所有成员变量和成员方法

堆内存 中分别记录了外部类对象和内部类对象

注意:在内部类对象中还隐含了外部类对象的地址。


二、静态内部类

  • 静态内部类也是成员内部类中的一种
  • 静态内部类只能访问外部类中的静态变量和静态方法,如果想要访问非静态的需要创建对象
  • 创建静态内部类对象的格式:外部类名.内部类名 对象名 = new 外部类名.内部类名();
  • 调用非静态方法的格式:先创建对象,用对象调用
  • 调用静态方法的格式:外部类名内部类名.方法名();
java 复制代码
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);
        }
    }
}
java 复制代码
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);
        }
    }
}
java 复制代码
public class Test {
    public static void main(String[] args) {
        Outer.Inner oi = new Outer.Inner();
        oi.method1();
        Outer.Inner.method2();
    }
}

三、局部内部类

  • 1.将内部类定义在方法里面就叫做局部内部类,类似于方法里面的局部变量。
  • 2.外界是无法直接使用,需要在方法内部创建对象并使用。
  • 3.该类可以直接访问外部类的成员,也可以访问方法内的局部变量。
java 复制代码
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.创建对象

接口

java 复制代码
public interface Swim {
    public void swim();
}

抽象类

java 复制代码
public abstract class Animal {
    public abstract void cat();
}

匿名内部类创建

java 复制代码
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 小时前
2M的带宽怎么怎么设置tcp滑动窗口以及连接池
java·网络·网络协议·tcp/ip
霖雨2 小时前
使用Visual Studio Code 快速新建Net项目
java·ide·windows·vscode·编辑器
SRY122404192 小时前
javaSE面试题
java·开发语言·面试
Fiercezm3 小时前
JUC学习
java
无尽的大道3 小时前
Java 泛型详解:参数化类型的强大之处
java·开发语言
ZIM学编程3 小时前
Java基础Day-Sixteen
java·开发语言·windows
我不是星海3 小时前
1.集合体系补充(1)
java·数据结构
放逐者-保持本心,方可放逐3 小时前
react 组件应用
开发语言·前端·javascript·react.js·前端框架
P.H. Infinity3 小时前
【RabbitMQ】07-业务幂等处理
java·rabbitmq·java-rabbitmq
爱吃土豆的程序员3 小时前
java XMLStreamConstants.CDATA 无法识别 <![CDATA[]]>
xml·java·cdata