初识内部类

内部类

什么是内部类? 定义在一个类里面的类就叫内部类,相对而言包含内部类的类就叫外部类

//外部类
class Outer{
    //内部类(在类的内部定义一个类)
    class Inner{
    }
}

内部类的特点:

  • 编译之后可生成独立的字节码文件。
  • 内部类可直接访问外部类的私有成员,而不破坏封装。
  • 可为外部类提供必要的内部功能组件。

内部类可以分为 --> 成员内部类、静态内部类、局部内部类、匿名内部类。

成员内部类

  • 在类的内部定义,与实例变量、实例方法同级别的类(这个“级别”指的是访问的级别)

    //外部类
    class Outer2{
        //实例变量
        private String name = "张三";
        //方法
        public void show(){
        }
        //成员内部类
        class Inner2{
        }
    }
    
  • 与实例变量、实例方法一样,想要使用成员内部类,就必须先创建外部类对象,由外部类对象来创建内部类对象,即成员内部类对象的创建必须依赖外部类的对象

  • 当外部类、内部类存在重名属性时,会优先访问内部类属性。

  • 成员内部类不能定义静态成员。

    public class Demo02 {
        public static void main(String[] args) {
            
    //        //先创建外部类对象
    //        Outer2 outer2 = new Outer2();
    //        //再创建内部类对象
    //        Outer2.Inner2 inner2 = outer2.new Inner2();
    
            //一步创建内部类对象
            Outer2.Inner2 inner2 = new Outer2().new Inner2();
            inner2.show();
        }
    }
    
    //外部类
    class Outer2{
    
        //实例变量
        private String name = "张三";
        private int age = 10;
    
        //成员内部类
        class Inner2{
    
            private String address = "北京";
            private String phone = "123412";
            //        private static int age = 10;  内部类中不能定义静态变量
            private static final int years = 10; //但是可以定义静态常量。
            //如果内部类属性与外部类属性重名,优先输出内部类属性
            private String name = "李四";
    
            //内部类方法
            void show(){
                //输出外部类的属性
                //与内部类属性重名时,使用 [外部类名.this.属性] 来区分属性
                System.out.println(Outer2.this.name);
                //也可以直接访问外部类属性(没有重名属性)
                System.out.println(age);
    
                //输出内部类的属性
                System.out.println(this.address);
                System.out.println(this.phone);
            }
        }
    }
    

静态内部类(很少使用)

静态内部类即在成员内部类前加static关键字

//外部类
class Outer3{
    //静态内部类,它的级别和外部类相同
    static class Inner3{ //注意:static只能修饰内部类,不可以修饰外部类。
    }
}
  • 不依赖外部类对象,可直接创建或通过类名访问,可声明静态成员。
  • 只能直接访问外部类的静态成员(实例成员实例化外部类对象)。
public class Demo03 {
    public static void main(String[] args) {

        //创建静态内部类对象
        Outer3.Inner3 inner3 = new Outer3.Inner3();
        inner3.show();
    }
}

//外部类
class Outer3{
    private String name = "张三";
    private  int age = 10;

    //静态内部类,它的级别和外部类相同
    static class Inner3{ //注意:static只能修饰内部类,不可以修饰外部类。
        private String address = "上海";
        private String phone = "234";

        public static int year = 123; //可以定义静态变量
        void show(){
            //静态内部类调用外部类属性时,和其他类调用外部类属性一样要创建对象
            Outer3 outer3 = new Outer3();
            //输出外部类的属性
            System.out.println(outer3.name);
            System.out.println(outer3.age);

            //输出内部类属性
            System.out.println(this.address);
            System.out.println(this.phone);
        }

    }
}

局部内部类

定义在外部类方法中,作用范围和创建对象范围仅限于当前方法

//外部类
class Outer4{
    private int age = 35;
    void show(){
        //局部内部类:定义在方法的内部
        class Inner{
            
        }
    }
}
  • 局部内部类访问外部类当前方法中的局部变量时,因无法保障变量的生命周期与自身相同,变量必须修饰为final。有兴趣可以了解一下方法的生命周期和垃圾回收机制。
  • 限制类的使用范围。局部内部类只能在当前方法中使用。
public class Demo04 {
    public static void main(String[] args) {
        //创建外部对象
        Outer4 outer = new Outer4();
        outer.show();
    }
}

//外部类
class Outer4 {

    private String name = "张三";
    private int age = 35;

    void show() {
        //定义局部变量
        final String address = "上海";

        //局部内部类:不能加任何访问修饰符
        class Inner {
            //局部内部类的属性
            private String phone = "242343";
            //不能定义静态变量,可以定义静态常量
//            private static int count = 134;
            private final static int count = 123;

            public void show2() {
                //访问外部类的属性
                System.out.println(Outer4.this.name);

                //访问内部类的属性
                System.out.println(this.phone);

                //访问局部变量,jdk1.7要求,变量必须时常量final,jdk1.8自动添加final。
                System.out.println(address);//这里实际放的是常量 "上海"。
            }
        }
        //如果局部内部类里使用了局部变量,则变量不可被修改了。
        //思考:如果show()方法消失了,Inner类会立即消失吗?show2()方法会消失吗?
        //如果address是变量可行吗?
//        address = "12312";
        //创建局部类对象
        Inner inner = new Inner();
        inner.show2();
    }
}

匿名内部类

匿名内部类在内部类中使用最频繁,它有以下几个特点

  • 没有类名的局部内部类(一切特征都与局部内部类相同)。
  • 必须继承一个父类或者实现一个接口。
  • 定义类、实现类.创建对象的语法合并,只能创建一个该类的对象。
//定义一个接口
public interface Usb {
    //服务
    void service();
}

public class Demo05 {
    public static void main(String[] args) {

        //局部内部类
//        class Fan implements Usb{
//            @Override
//            public void service() {
//                System.out.println("链接电脑。");
//            }
//        }

        //使用局部内类创建对象
//        USB usb = new Fan();//多态的使用
//        usb.service();

        //使用匿名内部类优化,实现了Usb接口
        Usb usb = new Usb(){//相当于创建了一个局部内部类
        	//内部实现了Usb内的方法
            @Override
            public void service() {
                System.out.println("链接电脑。");
            }
        };//注意:加了分号
        usb.service();
    }
}

优点:减少代码量.(有一些类可能只使用一次,没必要创建单独的一个类)
缺点:可读性较差。

ps:以上是本人学习内部类的笔记和一些个人的思考,对内部类做了一个简单的介绍,对于有些问题没有做深入的解释(自己也不是很懂ヽ(*。>Д<)o゜)。希望对你有所帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值