你知道内部类吗?

什么是内部类

将一个类A定义在另一个类B里面,里面的那个类A就称为内部类,B则称为外部类

成员内部类
  • 成员内部类 :定义在类中方法外的类。

定义格式:

class 外部类 {
    class 内部类{

    }
}

在描述事物时,若一个事物内部还包含其他事物,就可以使用内部类这种结构。比如,汽车类Car 中包含发动机类Engine ,这时,Engine就可以使用内部类来描述,定义在成员位置。

代码举例:

class Car { //外部类
    class Engine { //内部类

    }
}
访问特点
  • 内部类可以直接访问外部类的成员,包括私有成员。
  • 外部类要访问内部类的成员,必须要建立内部类的对象。

创建内部类对象格式:

外部类名.内部类名 对象名 = new 外部类型().new 内部类型()

访问演示,代码如下:

public class Body {// 外部类

    // 成员变量
    private int numW = 10;

    int num = 100;

    // 成员方法
    public void methodW1(){
        System.out.println("外部类中的methodW1方法...");
    }

    public void methodW2(){
        System.out.println("外部类中的methodW2方法...");
        // 创建内部类对象
        Body.Heart bh = new Body().new Heart();
        // 访问内部类成员变量
        System.out.println("内部类成员变量numN:"+bh.numN);
        // 访问内部类成员方法
        bh.methodN2();
    }

    public class Heart{// 成员内部类
        // 成员变量
        int numN = 20;

        int num = 200;

        // 成员方法
        public void methodN(){
            System.out.println("内部类中的methodN方法...");
            // 访问外部类成员变量
            System.out.println("外部类成员变量:"+numW);
            // 访问外部类成员方法
            methodW1();
        }

        public void methodN2(){
            System.out.println("内部类中的methodN2方法...");
        }

        public void methodN3(){
            int num = 300;
            System.out.println("局部变量num:"+num);// 300
            System.out.println("内部类成员变量num:"+this.num);// 200
            System.out.println("外部类成员变量num:"+Body.this.num);// 100
        }
    }
}
public class Demo {
    public static void main(String[] args) {
        // 测试
        // 创建外部类对象,调用外部类的方法methodW2
        Body body = new Body();
        body.methodW2();

        System.out.println("=======================");

        // 创建内部类对象,调用内部类的methodN方法
        Body.Heart heart = new Body().new Heart();
        heart.methodN();

        System.out.println("=======================");
        heart.methodN3();// 300  200  100
    }
}


小结:

内部类:将一个类A定义在另一个类B里面,里面的那个类A就称为内部类,B则称为外部类。
成员内部类的格式:
    public class 外部类名{
         public class 内部类名{

        }
    }
成员内部类的访问特点:
    - 内部类可以直接访问外部类的成员,包括私有成员。
    - 外部类要访问内部类的成员,必须要建立内部类的对象。

成员内部类的创建方式:
    外部类名.内部类名 对象名 = new 外部类名().new 内部类名();

匿名内部类

概述
  • 匿名内部类 :是内部类的简化写法。它的本质是一个带具体实现的 父类或者父接口的 匿名的 子类对象
代码一
public abstract class Animal {
    public abstract void eat();
}
public class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("狗吃骨头...");
    }
}
public class Test {
    public static void main(String[] args) {
        /*
            - 匿名内部类的概述:本质就是继承了父类或者实现了接口的匿名子类的对象
            - 匿名内部类的格式:
                new 类名\接口名(){
                    方法重写
                };

            - 匿名内部类的作用: 为了简化代码,并没有什么特殊的功能

            需求: 调用Aniaml类的eat()方法
            1.创建一个子类继承Animal类
            2.在子类中重写eat方法
            3.创建子类对象
            4.使用子类对象调用eat方法

            想要调用抽象类中的方法,必须具备以上4步,那能不能减后呢? 可以 使用匿名内部类
         */
        Animal anl1 = new Dog();
        anl1.eat();

        Animal anl2 = new Animal() {
            @Override
            public void eat() {
                System.out.println("Animal子类的eat方法...");
            }
        };
        anl2.eat();

    }
}
代码二
public interface AInterface {
    void method();
}
public class AImp implements AInterface {
    @Override
    public void method() {
        System.out.println("AImp 实现类重写method方法....");
    }
}
public class Demo {
    public static void main(String[] args) {
        /*
             匿名内部类:
                本质是一个继承了父类的匿名子类的对象
                本质是一个实现了接口的匿名实现类的对象

              案例: A接口中有一个抽象方法method(),现在需要调用A接口中的method方法
              思路:
                1.创建一个实现类实现A接口
                2.重写A接口中的抽象方法method()
                3.创建实现类对象
                4.使用实现类对象调用method方法

               想要调用A接口中的method方法,按照传统方式,必须有以上4步,一步都不可少
               前面三步就是为了得到A接口的实现类对象

            现在: 匿名内部类可以表示一个接口的匿名实现类对象,所以,可以直接创建接口的匿名内部类来调用method方法即可
         */
        AInterface a = new AInterface(){
            @Override
            public void method() {
                System.out.println("匿名内部类方式重写method方法....");
            }
        };
        a.method();

        System.out.println("==================");

        AInterface a2 = new AImp();
        a2.method();

        System.out.println("======================");
        AInterface a3 = new AInterface() {
            @Override
            public void method() {
                // 实现
            }
        };
    }
}

小结

 概述: 本质就是一个接口\父类的匿名子类对象
 格式:
     new 接口名\父类名(){ 重写抽象方法 };
 使用场景:
   如果需要得到一个抽象类的子类对象,那么就直接给该抽象类的匿名内部类即可
   如果需要得到一个接口的实现类对象,那么就直接给该接口的匿名内部类即可
<think>好的,我现在需要回答用户关于Java内部类构造器的问题。用户想知道内部类是否可以拥有构造器,以及如何定义和使用它们。让我先回忆一下相关的知识,并结合提供的引用内容来组织答案。 首先,根据引用[3],内部类分为成员内部类、局部内部类、匿名内部类和静态内部类。每种内部类的构造器可能有所不同。例如,成员内部类和静态内部类属于的成员,而匿名内部类则没有显式的名,构造器可能有所不同。 接下来,引用[4]提到匿名内部类虽然没有名字,但确实有自己的构造器。这里可能需要进一步解释,因为匿名内部类的构造器通常是通过实例初始化块来模拟的,或者调用父的构造器。例如,在实现接口或继承时,匿名内部类可以使用父的构造方法。 引用[5]讨论了匿名内部类是否继承Object的问题,用户尝试在其中添加toString方法,发现确实有Object的内容。这说明匿名内部类即使实现接口,也会默认继承Object,因此它们的构造器可能涉及到父的构造方法,比如调用super()。 对于成员内部类,引用[1]和[3]指出成员内部类属于外部的实例成员,所以它们的实例化需要依赖外部的实例。因此,成员内部类的构造器在定义时可能需要访问外部的引用,比如在构造器中隐式传递外部的实例。 静态内部类,如引用[1]提到的,是使用static修饰的内部类,它们不依赖于外部的实例,因此它们的构造器可以像普通的构造器一样定义和使用,直接通过外部名访问。 关于构造器的定义,根据引用[2],默认构造器是当没有显式定义构造器时由编译器生成的。对于内部类来说,如果没有定义构造器,编译器也会生成默认的无参构造器。但如果需要参数,就需要显式定义构造器。 现在需要将这些信息整理成结构清晰的回答,分点说明不同内部类的构造器情况,并举例说明如何定义和使用。同时,需要确保使用正确的LaTeX格式,如变量用$...$,代码块用```包裹,引用标识放在相关段落后。 最后,生成相关问题,参考用户提供的示例,围绕内部类的构造器、使用场景、与外部的关系等方面提问。</think>### 内部类构造器的定义与使用 在Java中,**内部类可以拥有构造器**,但具体定义和使用方式取决于内部类型。以下是四内部类的构造器特性及示例: --- #### 1. 成员内部类(非静态内部类) - **定义**:成员内部类属于外部的实例成员,因此**必须通过外部实例访问**。其构造器可以显式定义,但**隐含对外部实例的引用**。 - **构造器规则**: - 可以定义带参数的构造器; - 默认生成无参构造器(若未显式定义); - 构造器中隐式调用`外部对象.super()`以确保正确绑定外部实例[^3]。 - **示例**: ```java public class Outer { // 成员内部类 public class Inner { private String name; // 显式定义构造器 public Inner(String name) { this.name = name; } } } // 使用方式 Outer outer = new Outer(); Outer.Inner inner = outer.new Inner("内部类实例"); ``` --- #### 2. 静态内部类 - **定义**:使用`static`修饰的内部类,**不依赖外部实例**,构造器定义与普通一致[^1]。 - **构造器规则**: - 可自定义任意参数构造器; - 默认生成无参构造器; - 无法访问外部的非静态成员。 - **示例**: ```java public class Outer { // 静态内部类 public static class StaticInner { public StaticInner(int value) { System.out.println("静态内部类构造器,参数值:" + value); } } } // 使用方式 Outer.StaticInner inner = new Outer.StaticInner(10); ``` --- #### 3. 局部内部类(方法内部类) - **定义**:在方法或代码块中定义的,**仅在该作用域内可用**。 - **构造器规则**: - 可定义显式构造器; - 不能使用访问修饰符(如`public`); - 可访问方法内的`final`或等效不可变变量。 - **示例**: ```java public class Outer { public void method() { class LocalInner { // 局部内部类构造器 public LocalInner() { System.out.println("局部内部类实例化"); } } LocalInner inner = new LocalInner(); } } ``` --- #### 4. 匿名内部类 - **定义**:没有名的内联,通常用于实现接口或继承。**构造器通过实例初始化块模拟**[^4][^5]。 - **构造器规则**: - 无法显式定义构造器; - 使用代码块`{ ... }`初始化成员; - 可调用父构造器(如`super(param)`)。 - **示例**: ```java // 通过父构造器初始化 Runnable task = new Runnable() { { System.out.println("匿名内部类初始化块"); } @Override public void run() { System.out.println("任务执行"); } }; ``` --- ### 关键区别总结 | 内部类型 | 构造器显式定义 | 依赖外部实例 | 访问权限 | |--------------|----------------|----------------|----------------| | 成员内部类 | ✔️ | ✔️ | 可访问外部成员 | | 静态内部类 | ✔️ | ❌ | 仅静态成员 | | 局部内部类 | ✔️ | 依赖方法上下文 | 局部变量需final| | 匿名内部类 | ❌ | 视父而定 | 通过初始化块 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值