java 内部类 局部内部类 匿名内部类 成员内部类 静态内部类
发布日期:2021-05-07 10:30:28 浏览次数:13 分类:原创文章

本文共 9175 字,大约阅读时间需要 30 分钟。

  • 基本介绍
    一个类的内部又完整的嵌套了另一个类结构.被嵌套的类称为内部类(inner class),嵌套其它类的类称为外部类(outher class),内部类最大的特点是可以直接访问私有属性,并且可以体现类与类之间的包含关系
    // 外部类class Outer{     	// 内部类	class Inner{     	}}// 其它类/外部其它类class Other{     }

内部类分类

  • 定义在外部类局部位置上(比如方法内):
    1. 局部内部类(有类名)
    2. 匿名内部类(没有类名)
  • 定义在外部类的成员位置上:
    1. 成员内部类(没有static修饰)
    2. 静态内部类(使用static修饰)

局部内部类

  • 局部内部类是定义在外部类的局部位置,比如方法中,并且有类名.
  • 可以直接访问外部类的所有成员,包含私有的
  • 不能添加访问修饰符,因为它的地位就是一个局部变量,但是可以使用final修饰,因为局部变量也可以使用final
  • 作用域:仅仅在定义它的方法或代码块中
public class LocalInnerClass {       public static void main(String[] args) {           Outer02 outer02 = new Outer02();        outer02.m1();    }}/** * 外部类 */class Outer02 {       private int n1 = 100;    private void m2(){           System.out.println("Outer02 m2()");    }    /**     * 方法     */    public void m1() {           /**         * 1.局部内部类是定义在外部类的局部位置,通常在方法内         * 3.不能添加访问修饰符,但是可以使用final修饰,加final就不能被继承         * 4.作用域: 仅仅在定义它的方法或代码块中         */        class Inner02 {    //局部内部类            /**             * 2.可以直接访问外部类的所有成员, 包含私有的             */            private int n1 = 800;            public void f1(){                   //5.局部内部类可以直接访问外部类的成员, 比如 n1 m2()                //6.如果外部类和局部内部类的成员重名时,默认遵循就近原则,如果想访问外部类的成员                //使用外部类名.this.成员去访问                //Outher02.this 本质就是外部类的对象,即哪个对象调用了m1(),Outher.this就是那个对象                System.out.println("n1= " + n1 + " 外部类的n1=" + Outher02.this.n1);                m2();            }        }        //6.外部类在方法中,可以创建Inner01对象,然后调用方法即可        Inner02 inner02 = new Inner02();        inner02.f1();    }    {           class Inner03{           }    }}// 输出n1= 100Outer02 m2()

匿名内部类

  • 本质是类
  • 内部类
  • 该类没有名字
  • 匿名内部类是定义在外部类的局部位置, 比如方法中,并且没有类名

基本语法:

	new 类或接口(参数列表){   			类体	};
public class Anonymous {       public static void main(String[] args) {           new Outher04().method();    }}class Outher04{    //外部类    /**     * 属性     */    private int n1 = 10;    /**     * 方法     */    public void method() {           // 基于接口的匿名内部类        // 需求: 想使用IA接口,并创建对象        // 传统方式: 写一个类,实现该接口,并创建对象        // 如果(Tiger/Dog)类只是使用了一次  => new Tiger().cry();        // 可以使用匿名内部类来简化开发        /**         * 编译类型: IA         * 运行类型: 匿名内部类 Outher04$1         * 底层会分配类名 Outher04$1         * class Outher04$1 implements IA {         *      @Override         *      public void cry() {         *          System.out.println("老虎叫唤");         *      }         * }         */        // jdk底层创建匿名内部类Outher04$1,并且立即创建了Outher04$1实例,并且把地址返回给tiger        IA tiger = new IA() {               @Override            public void cry() {                   System.out.println("老虎叫唤");            }        };        // tiger的运行类型: class com.ll.demo.innerclass.Outher04$1        System.out.println("tiger的运行类型: " + tiger.getClass());        // 老虎叫唤        tiger.cry();		//==================================================        // 基于类的匿名内部类        // father编译类型: Father        // father运行类型: Outher04$2        // 底层会创建匿名内部类,同时返回匿名内部类Outher04$2的对象        /*        *   class Outher04$2 extends Father {        *       @Override                public void test() {                System.out.println("匿名内部类重写了test方法");                }        *   }        * */        // 参数列表"jack"会传递给构造器        Father father = new Father("jack"){               @Override            public void test() {                   System.out.println("匿名内部类重写了test方法");            }        };        // father的运行类型: class com.ll.demo.innerclass.Outher04$2        System.out.println("father的运行类型: " + father.getClass());        // 匿名内部类重写了test方法        father.test();		//==================================================        //基于抽象类的匿名内部类        Animal animal = new Animal(){               @Override            void eat() {                   System.out.println("吃东西");            }        };        // class com.ll.demo.innerclass.Outher04$3        System.out.println("animal的运行类型: " + animal.getClass());        // 吃东西        animal.eat();    }}/** * 接口 */interface IA {       void cry();}/** * 传统方式 */class Tiger implements IA {       @Override    public void cry() {           System.out.println("老虎叫");    }}class Dog implements IA {       @Override    public void cry() {           System.out.println("狗叫");    }}class Father {       private String name;    public Father(String name){           this.name = name;    }        public void test() {               }}/** * 抽象类 */abstract class Animal {       abstract void eat();        public void test() {               }}

细节

public class AnonymousInnerClassDetail {       public static void main(String[] args) {           Outer05 outer05 = new Outer05();        outer05.f1();        // 1798286609        System.out.println(outer05.hashCode());    }}class Outer05 {       private int n1 = 99;    public void f1() {           // 创建一个基于类的匿名内部类        // 不能添加访问修饰符,因为它的地位就是一个局部变量        // 作用域: 仅仅在定义它的方法或代码块中        // 匿名内部可以直接访问外部类        Person person = new Person() {               private int n1 = 23;            @Override            public void hi() {                   // 可以直接访问外部类的所有成员,包含私有的                // 如果外部类和匿名内部类的成员重名时,匿名内部类访问的话                // 默认遵循就近原则,如果想访问外部类的成员,则使用(外部类名.this.成员)去访问                // 匿名内部类重写了hi方法, n1:23, 访问外部类的n1:99                System.out.println("匿名内部类重写了hi方法, n1:" + n1 + ", 访问外部类的n1:" + Outer05.this.n1);                // Outer05.this 就是调用f1的对象                // 1798286609                System.out.println(Outer05.this.hashCode());            }        };        //动态绑定,会执行重写后的方法,运行类型是Outer05$1        person.hi();        //也可以直接调用,匿名内部类本身也是返回对象        // class 匿名匿名内部类 extends Person{}        new Person() {               @Override            public void hi() {                   System.out.println("哈哈哈");            }            @Override            public void ok(String str) {                   System.out.println("ok" + str);            }        }.ok("123");    }}/** * 父类 */class Person {       public void hi() {           System.out.println("Person hi()");    }    public void ok(String str) {           System.out.println("Person ok()" + str);    }}// 抽象类/接口...
public class InnerClassExercise01 {       public static void main(String[] args) {           f1(new AA() {               @Override            public void show() {                   System.out.println("这是一幅名画");            }        });        new AA() {               @Override            public void show() {                   System.out.println("这是一幅名画");            }        }.show();    }    /**     * 静态方法, 形参是接口类型     * @param aa     */    public static void f1(AA aa) {           aa.show();    }}/** * 接口 */interface AA {       void show();}
public class InnerClassExercise02 {       public static void main(String[] args) {           CellPhone cellPhone = new CellPhone();        cellPhone.alarmclock(new Bell() {               @Override            public void ring() {                   System.out.println("手机闹钟");            }        });        cellPhone.alarmclock(new Bell() {               @Override            public void ring() {                   System.out.println("小伙伴们上课了");            }        });        new Bell(){               @Override            public void ring() {                   System.out.println("测试");            }        }.ring();    }}interface Bell {       void ring();}class CellPhone{       public void alarmclock(Bell bell) {           bell.ring();    }}

成员内部类

  • 成员内部类是定义在外部类的成员位置,并且没有static修饰
  • 可以直接访问外部类的所有成员,包含私有的
  • 可以添加任意访问修饰符(public,protected,默认,private),因为它的地址就是一个成员
public class MemberInnerClass01 {       public static void main(String[] args) {           Outer.Inner08 inner08 = new Outer().new Inner08();        // 10,张三        inner08.say();        // 10,张三        new Outer().test();    }}/** * 外部类 */class Outer {       private int n1 = 10;    public String name = "张三";    /**     * 成员内部类     */    class Inner08 {           public void say() {               System.out.println(n1  + "," + name);        }    }    public void test() {           Inner08 inner08 = new Inner08();        inner08.say();    }}

成员内部类练习

public class Homework07 {       public static void main(String[] args) {           Car car = new Car(-1);        car.getAir().flow();                new Car(60).new Air().flow();    }}class Car {       private double temperature;    public Car(double temperature) {           this.temperature = temperature;    }    class Air {           public void flow() {               if (temperature > 40) {                   System.out.println("冷气");            } else if(temperature < 0) {                   System.out.println("暖气");            } else {                   System.out.println("关闭空调");            }        }    }    public Air getAir() {           return new Air();    }}// 输出暖气冷气  

静态内部类

  • 静态内部类是定义在外部类的成员位置,并且有static修饰
  • 可以直接访问外部类的所有静态成员,包含私有的,但是不能访问非静态成员
  • 可以添加任意访问修饰符(public,protected,默认,private)
  • 作用域: 同其它的成员一样
public class StaticInnerClass01 {       public static void main(String[] args) {           Outer10.Inner10 inner10 = new Outer10.Inner10();        inner10.test();    }}/** * 外部类 */class Outer10 {       private int n1 = 10;    private static String name = "张三";    /**     * 静态内部类     */    static class Inner10 {           public void test() {               System.out.println(name);        }    }}
上一篇:java 实现接口 vs 继承类
下一篇:java 接口(Interface)多态特性

发表评论

最新留言

留言是一种美德,欢迎回访!
[***.207.175.100]2025年04月09日 03时36分33秒