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


相关推荐
.生产的驴5 分钟前
SpringBoot 消息队列RabbitMQ 消费者确认机制 失败重试机制
java·spring boot·分布式·后端·rabbitmq·java-rabbitmq
虚拟搬运工10 分钟前
Python类及元类的创建流程
开发语言·chrome·python
Code哈哈笑23 分钟前
【C++ 学习】多态的基础和原理(10)
java·c++·学习
chushiyunen28 分钟前
redisController工具类
java
消失的旧时光-194330 分钟前
kotlin的密封类
android·开发语言·kotlin
A_cot34 分钟前
Redis 的三个并发问题及解决方案(面试题)
java·开发语言·数据库·redis·mybatis
学步_技术34 分钟前
Python编码系列—Python原型模式:深克隆与高效复制的艺术
开发语言·python·原型模式
刘某某.40 分钟前
使用OpenFeign在不同微服务之间传递用户信息时失败
java·微服务·架构
alden_ygq40 分钟前
GCP容器镜像仓库使用
java·开发语言
七折困1 小时前
列表、数组排序总结:Collections.sort()、list.sort()、list.stream().sorted()、Arrays.sort()
java·集合·数组·排序