java基础之内部类

对于初学者而言,感觉内部类是多余的,但是随着对内部类的逐渐了解,就会发现他有独到的用处,学会使用内部类,是掌握Java高级编程的一部分,他能够让程序变得更优雅。

顶层类只能处于public和默认访问级别,而成员内部类可以处于public,protected,默认,private访问级别。

在外部类中可以直接使用内部类。 内部类的完整类名为: OuterClass.InnerClass

成员内部类分为 实例内部类和静态内部类,后者被static修饰。

实例内部类

1,在创建实例内部类的时候,外部类的实例必须存在。
2,实例内部类的实例自动持有外部类的实例引用。在内部类中可以自动引用外部类的成员变量和成员方法。在实例内部类中之所以能够直接引用外部类的成员变量和成员方法,是因为实例化内部类的使用,外部类已经实力化类。
3,外部类不能直接访问内部类的成员,必须通过内部类的实例来访问。
4,实例内部类中不能定义静态成员。
5,内部类和外部了有同名的成员时,在内部类中通过this.v访问内部类的成员变量,在内部类中通过 Outer.this.v访问外部类的成员。

静态内部类

1,静态内部类不会自动持有外部类特定实例的引用,在创建内部类的实例时,不必创建外部类的实例。
2,静态内部类可以直接访问外部类的静态成员,如果访问外部类的实例成员,则需要通过外部类的对象。
3,在静态内部类中可以定义静态变量和实例变量。
4,客户类可以通过完整的类名直接访问静态内部类的静态成员。

局部内部类

局部内部类是一个在方法中定义的内部类,它的范围是当前方法。和局部变量一样,局部内部类不用用访问控制符修饰,也不能用static修饰。
1,局部内部类只能在当前方法中使用。
2,局部内部类和实例内部类一样,不能包含静态成员。
3,可以访问外部类的所有成员。
4,局部内部类可以访问所在方法的符合一下方法的参数。
    4.1,用final修饰的变量。
    4.2,实际上的最终变量和参数:虽然没有用final修饰,但是程序不会修改变量的值。

子父类中的内部类同名

1,内部类不存在覆盖,如果子类和父类存在同名的内部类,那么这两个内部类有不同的命名空间,不会发生冲突。

匿名类

匿名类是一种特殊的内部类,这种类没有名字。
public class A {
    A(int v) { System.out.println("another constructor");}
    A() { System.out.println("default constructor");}
    void method(){ System.out.println("from A"); }

    public static void main(String[] args) {
        new A().method();//打印结果:from A
        A a=new A(){
            void method(){ System.out.println("from 匿名类");  }
        };
        a.method();//打印结果:from 匿名类
    }
}
1,匿名类没有构造方法,但是他会调用父类的构造方法。
2,匿名类虽然没有构造方法,但是可以在匿名类中提供一段实例初始化代码使用 { } 包围的代码快,JVM会在调用父类构造方法的时候执行这段代码。
3,除了可以在外部类的方法内定义匿名类,还可以在声明一个成员变量的时候定义匿名类。
4,匿名类除了可以继承类,还可以实现接口。
5,匿名类和局部类一样,可以访问外部类的所有成员,如果匿名类位于一个方法中,还可以访问所在方法的最终变量和参数,或者实际上的最终变量和参数。
6,局部内部类的名字在方法外是不可见的,隐藏匿名类也一样,能够起到封装类型名字的作用,局部内部类盒匿名类有一下区别:
    6.1:匿名类程序代码比较简短。
    6.2:一个局部内部类可以有多个重构方法,并且客户类可以多次创建局部内部类的实例。而匿名类没有重载构造方法,并且只能创建一次实例。

内部类的用途

1,封装类型:
    面向对象的核心之一是封装:把所有不希望对外公开的细节封装起来。
2,直接访问外部类的成员:
3,回调:
    回调实际上是指一个类尽管实际上实现了某种方法,但是没有直接提供相应的接口,客户类可以通过这个类的内部类的接口来获取这个功能,而这个内部类本身没有提供真实的实现,仅仅调用外部的实现。可见,回调充分发挥了内部类具有访问外部类的实现细节的优势。

    回调实例:
        public interface Adjustable {
            /** 调节温度 */
            public void adjust(int temperature);
        }

        public class Base {
            private int speed;
            /** 条件速度*/
            public void adjust(int speed){
                System.out.println("调节速度");
                this.speed=speed;
            }
        }

        public class Sub extends Base {
            private int temperature;
            private void adjustTemperature(int temperature) {
                this.temperature = temperature;
            }
            private class Closure implements Adjustable {
                @Override
                public void adjust(int temperature) {
                    System.out.println("调节温度");
                    adjustTemperature(temperature);
                }
            }
            public Adjustable getCallBackReference() {
                return new Closure();
            }
        }

        public class Running {
            public static void main(String[] args) {
                Sub sub = new Sub();
                Adjustable callBackReference = sub.getCallBackReference();
                callBackReference.adjust(15);
                sub.adjust(14);
            }
        }
上一篇:esp32学习-手把手搭建idf开发环境


下一篇:java lamada