第5章-第8节-Java面向对象中的内部类

1、内部类:属于类的成员之一,类的内部又定义类,外层的class称为外部类,内部的class称为内部类。

设计了某个类,根据需求发现其内部又需要定义一个独立的内部结构,此时就考虑将其定义为内部类,内部类依赖于外部类,不可能独立存在。

举例:
    母亲 和其 腹中的胎儿

备注:外部类的权限修饰只能用public或者缺省,而内部类可以用所有的四种权限。

2、内部类的分类:

定义位置:

1)、成员内部类: 定义在类的成员位置;
2)、局部内部类: 定义在类的局部位置; 

成员内部类细分:

1)、非静态成员内部类:非静态内部类;
2)、静态成员内部类:  静态内部类;

局部内部类细分:

1)、局部内部类:    定义在局部位置的有名类;  
2)、匿名内部类:    定义在局部位置的匿名类;


1、匿名内部类:内部类中,匿名内部类使用率最高,所以这里先进行说明,其它的内部类直接后面放代码里进行说明。

引入场景:
    类/接口内部定义了某方法,我需要使用该方法,但是发现方法体的逻辑不适合,
    根据之前学习过的技术,我们就定义一个类,让该类去继承父类/实现接口,
    重写其内部的方法,在外界实例化对象,对象调用方法完成需求。

    【问题】:辛辛苦苦设计完一个类,但是在外界只需要使用很少的次数(比如:一次)
              那么有点浪费了!!!

    【解决】:可以使用匿名内部类解决上述的问题

格式:

两种情况:

情况一:和父类有关

模板:
    new 父类名(){
        //设计匿名子类的成员
    };

情况二:和接口有关

模板:
    new 接口名(){
        //设计匿名实现类的成员
    };

解析格式:
    
内部包含两个环节:

环节一:设计匿名子类/实现类
环节二:创建匿名子类/实现类的对象

备注:匿名内部类不能赋值给对象引用,要调用时只能匿名类自己直接在后面.操作进行调用方法,例如下面这样三个例子:

//匿名内部类
new Father(){
    //重写method方法
    @Override
    public void method() {
        System.out.println("重写method");;
    }
}.method();

//匿名内部类
new Object(){
    public void myMethod() {
        System.out.println("匿名内部类自己的方法");
    }
}.myMethod();

//匿名内部类
new Inter(){
    //重写实现接口的interMethod方法
    @Override
    public void interMethod() {
        System.out.println("实现接口interMethod");
    }
}.interMethod();

3、成员内部类的几种情况:

1)、非静态内部类:

//外部类
public class Outer {
    //属性
    int a = 10;
    static int b = 20;
    private int c = 30;

    //方法
    public void outM1() {
        System.out.println("out...m1");
    }

    public static void outM2() {
        System.out.println("out...m2");
    }

    public void outM5() {
        /*
            非静态方法内部访问非静态内部类的成员
            步骤如下:
                1).创建非静态内部类对象
                2).非静态内部类对象访问其内部成员
         */
        Inner in = this.new Inner();
        System.out.println(in.i);
        in.inM3();
    }

    public static void outM6() {
        /*
            静态方法内部访问非静态内部类的成员
            步骤如下:
                1).创建外部类对象
                2).通过外部类对象去创建非静态内部类对象
                3).非静态内部类对象访问其内部成员
         */
        Outer o = new Outer();
        Inner in = o.new Inner();
        System.out.println(in.i);
        in.inM3();
    }

    //设计非静态内部类
    class Inner{
        int i = 100;

        //非静态内部类中不能定义静态属性
//        static int j = 200;

        //非静态内部类中可以定义常量
        static final double PI = 3.14;

        public void inM3() {
            System.out.println("in...m3");
        }

        //非静态内部类中不能定义静态方法
//        public static void inM4() {
//            //...
//        }

        {}
        //非静态内部中不能定义静态代码块
//        static{}

        public void test() {
            //访问外部类的属性
            System.out.println(a);
            System.out.println(Outer.this.a);
            System.out.println(b);
            System.out.println(Outer.b);
            System.out.println(c);

            //访问外部类的方法
            Outer.this.outM1();
            Outer.outM2();
        }
    }
}
public class Test {
    public static void main(String[] args) {
        /*
            在外界(比如:测试类),访问非静态内部类的成员
            步骤如下:
                1).创建外部类对象
                2).通过外部类对象去创建非静态内部类对象
                3).非静态内部类对象访问成员
         */
        Outer o = new Outer();
        Outer.Inner in = o.new Inner();
        System.out.println(in.i);
        in.inM3();
    }
}

2)、静态内部类:

public class Outer {
    //属性
    int a = 10;
    static int b = 20;
    private int c = 30;

    //方法
    public void outM1() {
        System.out.println("out...m1");
    }

    public static void outM2() {
        System.out.println("out...m2");
    }

    public void outM5() {
        /*
            外部类非静态方法内部可以直接访问静态内部类的静态成员(属性、方法)
            通过类名.静态成员
         */
        System.out.println(Inner.j);
        Inner.inM4();

        /*
            外部类非静态方法内部不可以直接访问静态内部类的非静态成员(属性、方法)
            但是可以间接访问,步骤如下:
                1).创建静态内部类对象
                2).通过静态内部类对象访问其非静态成员
         */
        Inner in = new Inner();
        System.out.println(in.i);
        in.inM3();
    }

    public static void outM6() {
        /*
            外部类静态方法内部可以直接访问静态内部类的静态成员(属性、方法)
            通过类名.静态成员
         */
        System.out.println(Inner.j);
        Inner.inM4();

        /*
            外部类静态方法内部不可以直接访问静态内部类的非静态成员(属性、方法)
            但是可以间接访问,步骤如下:
                1).创建静态内部类对象
                2).通过静态内部类对象访问其非静态成员
         */
        Inner in = new Inner();
        System.out.println(in.i);
        in.inM3();
    }

    //设计静态内部类
    static class Inner{

        int i = 100;
        static int j = 200;

        public void inM3() {
            System.out.println("in...m3");
        }

        public static void inM4() {
            System.out.println("in...m4");
        }

        public void test() {
            /*
                静态内部类非静态方法内部可以直接访问外部类的静态成员:
                直接通过类名.静态成员即可
             */
//            System.out.println(a);
            System.out.println(Outer.b);
            Outer.outM2();

            /*
                静态内部类非静态方法内部不可以直接访问外部类的非静态成员:
                必须先创建外部类对象,在通过对象名.非静态成员
             */
            Outer o = new Outer();
            System.out.println(o.a);
            System.out.println(o.c);
            o.outM1();


        }

        public static void test2() {
            /*
                静态内部类静态方法内部可以直接访问外部类的静态成员:
                直接通过类名.静态成员即可
             */
//            System.out.println(a);
            System.out.println(Outer.b);
            Outer.outM2();

            /*
                静态内部类静态方法内部不可以直接访问外部类的非静态成员:
                必须先创建外部类对象,在通过对象名.非静态成员
             */
            Outer o = new Outer();
            System.out.println(o.a);
            System.out.println(o.c);
            o.outM1();


        }
    }
}
public class Test {
    public static void main(String[] args) {
        //访问静态内部类的静态成员(属性、方法) ==> 类名直接访问
        System.out.println(Outer.Inner.j);
        Outer.Inner.inM4();

        /*
            访问静态内部类的非静态成员(属性、方法)
            先创建静态内部类对象,在通过对象访问非静态成员
         */
        Outer.Inner in = new Outer.Inner();
        System.out.println(in.i);
        in.inM3();
    }
}

4、关于内部类的一个小案例:

class Wai{
    int a = 10;
    class Nei{
        int a = 100;
        public void test() {
            int a = 1000;
            System.out.println("局部变量a=" + a);                   //就近原则  a=1000
            System.out.println("非静态内部类成员变量a=" + this.a);    //a=100
            System.out.println("外部类成员变量a=" + Wai.this.a);     //a=10
        }
    }
}

public class Exer {
    public static void main(String[] args) {
        Wai w = new Wai();
        Wai.Nei n = w.new Nei();
        n.test();
    }
}

本电子书目录:《Java基础的重点知识点全集》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zwarwolf

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值