内部类之成员内部类

我们在阅读源码的过程中,会遇到很多内部类,让我们阅读难度增加。这篇文章主要介绍成员内部类的作用

1.成员内部类可以访问外部类的所有方法和成员变量(不论是静态的还是非静态的)

package com.high.concurrency.inner;

/**
 * @author yangmin
 * @version 1.0
 * @description: 成员内部类: 不可以有静态成员变量,但是可以反问外部类的任何(静态和非静态的)成员变量和方法
 *
 * 可以无条件地访问外围类的所有元素
 * 为什么可以引用:内部类虽然和外部类写在同一个文件中, 但是编译完成后, 还是生成各自的class文件,内部类通过this访问外部类的成员。
 * 编译器自动为内部类添加一个成员变量, 这个成员变量的类型和外部类的类型相同, 这个成员变量就是指向外部类对象(this)的引用;
 * 编译器自动为内部类的构造方法添加一个参数, 参数的类型是外部类的类型, 在构造方法内部使用这个参数为内部类中添加的成员变量赋值;
 * 在调用内部类的构造函数初始化内部类对象时,会默认传入外部类的引用。
 * @date 2023/6/28 16:36
 */
public class MemberInnerClass_1 {
    private static String name="外部类的静态变量";
    private String value="外部类的非静态变量";

    private static void m1(){
        System.out.println("外部类的静态方法");
    }

    private void m2(){
        System.out.println("外部类的非静态方法");
    }

    public static String getName() {
        return name;
    }

    public static void setName(String name) {
        MemberInnerClass_1.name = name;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    private class InnerClass{
        public InnerClass(){
        }

        public void out(String name1,String value1){
            System.out.println(name);
            System.out.println(value);
            name=name1;
            value=value1;
            System.out.println(name);
            System.out.println(value);
            m1();
            m2();
        }
    }

    public static void main(String[] args) {

        //内部类创建实例的方式
        InnerClass innerClass1 = new MemberInnerClass_1().new InnerClass();
        MemberInnerClass_1 memberInnerClass11 = new MemberInnerClass_1();
        InnerClass innerClass2 = memberInnerClass11.new InnerClass();

        innerClass2.out("内部类修改了外部类的静态变量","内部类修改了外部类的非静态变量");
    }
}

运行结果:
在这里插入图片描述

成员内部类可以对同一包下的其他类隐藏

成员内部类的修饰符: private protected, defaule, public`
首先我们定义一个接口

public interface TestInterface{
    void test();
}

定义一个内部类实现上面的接口,注意内部类用private修饰符修饰,这样可以防止其他的类的访问;外部类提供获取内部类实例的方法,返回值类型是接口类型

/**
 * @author yangmin
 * @version 1.0
 * @description: 测试内部类对同一包下的类做隐藏
 * @date 2023/6/29 10:06
 */
public class MemberInnerClass_2 {

    public TestInterface getInner() {
        return new Inner();
    }

  private  class Inner implements TestInterface {

        @Override
        public void test() {
            System.out.println("我是MemberInnerClass_2的内部类");
        }
    }
}

在同一个包下新建一个类进行访问

package com.high.concurrency.inner;

/**
 * @author yangmin
 * @version 1.0
 * @description: TODO
 * @date 2023/6/29 10:18
 */
public class Test2 {
    public static void main(String[] args) {
        MemberInnerClass_2 memberInnerClass2 = new MemberInnerClass_2();
        TestInterface testInterface = memberInnerClass2.getInner();
        testInterface.test();
    }
}

测试结果:
在这里插入图片描述
分析: private修饰符修饰内部类使得外部类无法通过外部类访问, 实现接口并且外部类提供了返回内部类的方法,但是返回类型是内部类实现的接口类型,当外部类通过该方法时获取的是接口类型, 实现了内部类的隐藏

可以解决单继承的问题

首先我们定义两个父类

public class FuOne {
    void m(){
        System.out.println("FuOne的方法");
    }
}


public class FuTwo {
    void m(){
        System.out.println("FuTwo的方法");
    }
}

定义一个外部类和两个内部类,并让这两个内部类分别继承上面的父类

package com.high.concurrency.inner;

/**
 * @author yangmin
 * @version 1.0
 * @description: TODO
 * @date 2023/6/29 10:55
 */
public class MemberInnerClass_3 {

    private class SunOne extends FuOne{

    }

    private class SunTwo extends FuTwo{

    }

    public void m1(){
        new SunOne().m();
    }

    public void m2(){
        new SunTwo().m();
    }
}

测试类及结果

package com.high.concurrency.inner;

/**
 * @author yangmin
 * @version 1.0
 * @description: TODO
 * @date 2023/6/29 10:18
 */
public class Test2 {
    public static void main(String[] args) {
       MemberInnerClass_3 memberInnerClass3 = new MemberInnerClass_3();
        memberInnerClass3.m1();
        memberInnerClass3.m2();
    }
}

结果:
在这里插入图片描述

补充

  • 成员内部类不能定义静态变量和静态方法, 可以反问外部类的任何的方法和变量
  • 内部类的创建依赖外部类的实例对象,在没有外部类实例之前是无法创建内部类的
  • 创建内部类的方法
public class ClassOuter {
    public void fun(){
        System.out.println("外部类方法");
    }
    public class InnerClass{  
    }
}

public class TestInnerClass {
    public static void main(String[] args) {
        //创建方式1
        ClassOuter.InnerClass innerClass = new ClassOuter().new InnerClass();
        //创建方式2
        ClassOuter outer = new ClassOuter();
        ClassOuter.InnerClass inner = outer.new InnerClass();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值