【JAVA】内部类

描述

一个类的内部又完整的嵌套了另外一个类结构,被嵌套的类称为内部类(inner class),内部类属于类的五大成员(属性、方法、构造器、代码块、内部类) 之一,内部类最大的特点是可以直接访问私有属性,并且可以体现类与类之间的包含关系。

局部内部类

如果类定义在方法或者代码块中,称为局部内部类,无类名的称为匿名内部类。

①可以直接访问外部类的所有成员,包含私有成员
②不能添加访问修饰符,因为它的地位就是一个局部变量。局部变量是不能使用修饰符的。但是可以使用final修饰,因为局部变量也可以使用final
③作用域和局部变量一样
④外部类访问局部内部类的成员,需要先创建对象,再访问(必须在作用域之内)
⑤如果外部类和局部内的成员重名时,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员名)去访问

普通局部内部类

样例代码:

package com.liuranli;

public class test {
    public static void main(String[] args) {
        new Outer().m1();
    }
}


class Outer {
    private int n1 = 100;

    private void m2() {
        System.out.println("Outer m2()");
    }

    public void m1() {
        final class Inner {
            private int n1 = 200;

            public void f1() {
                System.out.println("n1 = " + n1 + "外部类的n1 = " + Outer.this.n1);
                System.out.println("Outer.this.hashcode = " + Outer.this);
                m2();   //调用外部类的m2方法
            }
        }
        Inner inner = new Inner();  //创建内部类对象
        inner.f1(); //执行内部类的f1方法
    }
}

样例输出:

n1 = 200外部类的n1 = 100
Outer.this.hashcode = com.liuranli.Outer@614c5515
Outer m2()

局部内部类定义在方法或代码块中,有类名,作用域在方法体或者代码块中,其本质任是一个类。

匿名内部类

样例代码:

package com.liuranli;

public class test {
    public static void main(String[] args) {
        new Outer02().method();
    }
}

class Outer02 {
    private int n1 = 10;

    public void method() {
        //基于接口的匿名内部类
        IA tiger = new IA() {
            @Override
            public void cry() {
                System.out.println("老虎在叫唤~");
            }
        };  //加分号结束
        System.out.println("tiger的运行类型=" + tiger.getClass());
        tiger.cry();
        //基于外部其它类的匿名内部类
        Father father = new Father("张三") {
            @Override
            public void test() {
                System.out.println("匿名内部类重写了father类的test方法");
            }
        };
        System.out.println("father的运行类型=" + father.getClass());
        father.test();
        //基于抽象类的匿名内部类
        Animal animal = new Animal() {
            @Override
            void eat() {
                System.out.println("小狗吃骨头");
            }
        };
        System.out.println("animal的运行类型=" + animal.getClass());
        animal.eat();
    }
}

//接口
interface IA {
    public void cry();
}

class Father {
    public Father(String name) {
        System.out.println("接收到name = " + name);
    }

    public void test() {
    }
}

//抽象类
abstract class Animal {
    abstract void eat();
}

样例输出:

tiger的运行类型=class com.liuranli.Outer02$1
老虎在叫唤~
接收到name = 张三
father的运行类型=class com.liuranli.Outer02$2
匿名内部类重写了father类的test方法
animal的运行类型=class com.liuranli.Outer02$3
小狗吃骨头

样例代码2(做实参传递):

package com.liuranli;
/*
* 有一个铃声接口Bell,里面有一个ring方法。
* 有一个手机类Cellphone,具有闹钟功能alarmclock,参数是Bell类型。
* 测试手机类的闹钟功能,通过匿名内部类作为实参。
* */

public class test {
    public static void main(String[] args) {
        new Cellphone().alarmClock(new Bell() {
            @Override
            public void ring() {
                System.out.println("起床了");
            }
        });
        new Cellphone().alarmClock(new Bell() {
            @Override
            public void ring() {
                System.out.println("上课了");
            }
        });
    }
}

//铃声接口
interface Bell {
    public void ring();
}

//手机类
class Cellphone {
    public void alarmClock(Bell bell) {
        bell.ring();
    }
}

样例输出2(做实参传递):

起床了
上课了

匿名内部类使用一次就不能在使用了, jdk 底层在创建匿名内部类时会自动分配一个类名,类名为:外部类名称$序号 组成。

成员内部类

如果类定义在成员位置上,称为成员内部类,使用static修饰过的叫做静态内部类。
①可以直接访问外部类的所有成员,包含私有的
②可以添加任意访问修饰符(public、protected、private),因为它的地位就是一个成员。
③作用域和外部类的其他成员一样。
④外部类访问成员内部类,先创建对象,在访问。
⑤如果外部类和局部内的成员重名时,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员名)去访问。

成员内部类

样例代码:

package com.liuranli;

public class test {
    public static void main(String[] args) {
        new Outer03().t1();
        System.out.println("--------------------");
        new Outer03().getInner03Instance().say();
    }
}

class Outer03{
    private int n1 = 10;
    public String name = "张三";
    private void hi(){
        System.out.println("hi()方法...");
    }
    //成员内部类
    public class Inner03{
        private double sal = 99.7;
        private int n1 = 55;
        public void say(){
            System.out.println("n1 = " + n1 + " name = " + name + " 外部类的n1 = " + Outer03.this.n1);
            hi();
        }
    }
    //公有的用于返回成员内部类对象的方法
    public Inner03 getInner03Instance(){
        return new Inner03();
    }
    public void t1(){
        Inner03 inner03 = new Inner03();
        inner03.say();
        System.out.println(inner03.sal);
    }
}

样例输出:

n1 = 55 name = 张三 外部类的n1 = 10
hi()方法...
99.7
--------------------
n1 = 55 name = 张三 外部类的n1 = 10
hi()方法...

静态内部类

样例代码:

package com.liuranli;

public class test {
    public static void main(String[] args) {
        Outer04.Inner04 inner04 = new Outer04.Inner04();
        inner04.say();
        System.out.println("--------------------");
        Outer04 outer04 = new Outer04();
        Outer04.Inner04 inner041 = outer04.getInner04();
        inner041.say();
        System.out.println("--------------------");
        Outer04._getInner04().say();
    }
}

class Outer04{
    private int n1 = 10;
    private static String name = "张三";
    private static void cry(){

    }
    static class Inner04{
        private static String name = "zhangsan";
        public void say(){
            System.out.println("内部类name = " + name + " 外部类name = " + Outer04.name);
            cry();
        }
    }
    public Inner04 getInner04(){
        return new Inner04();
    }
    public static Inner04 _getInner04(){
        return new Inner04();
    }
}

样例输出:

内部类name = zhangsan 外部类name = 张三
--------------------
内部类name = zhangsan 外部类name = 张三
--------------------
内部类name = zhangsan 外部类name = 张三
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

孑然R

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

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

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

打赏作者

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

抵扣说明:

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

余额充值