• Java编程思想---第十章 内部类(下)


    第十章 内部类(下)

    10.9 内部类的继承

     

      因为内部类的构造器必须连接到指向其外围类对象的引用,所以在继承内部类的时候事情会变得有些复杂,问题在于那个指向外围类对象的引用必须被初始化,而在导出类中不再存在可连接的默认对象,要解决这个问题,必须使用特殊的语法来明确说清他们之间的关联:

    class WithInner {
        class Inner {}
    }
    
    public class InheritInner extends WithInner.Inner {
        InheritInner(WithInner wi) {
            wi.super();
        }
        public static void main(String[] args) {
            WithInner wi = new WithInner();
            InheritInner ii = new InheritInner(wi);
        }
    }

     

      可以看到,InheritInner只继承自内部类,而不是外围类,但是当要生成一个构造器时,默认的构造器并不算好,而且不能只是传递一个指向外围类对象的引用,此外必须在构造器内使用如下的语法:

    enclosingClassReference.super();

     

    10.10 内部类可以被覆盖吗

     

      如果创建了一个内部类,然后继承其外围类并重新定义此内部类时会发生什么呢?内部类可以被覆盖吗?我们看下面的例子:

    class Egg {
        private Yolk y;
        protected class Yolk {
            public Yolk() {
                System.out.println("Egg.Yolk()");
            }
        }
        public Egg() {
            System.out.println("New Egg()");
            y = new Yolk();
        }
    }
    
    public class BigEgg extends Egg{
        public class Yolk {
            public Yolk() {
                System.out.println("BigEgg.Yolk()");
            }
        }
        public static void main(String[] args) {
            new BigEgg();
        }
    }

     

    输出结果为:

    New Egg()

    Egg.Yolk()

     

      默认构造器是编译器自动生成的,这里是调用基类的默认构造器。这个例子说明,当继承了摸个外围类的时候内部类并没有发生什么特别的变化,这两个内部类是完全独立的实体,各自在自己的命名空间内。

     

    10.11 局部内部类

     

      在代码块里创建内部类,典型的方式是在一个方法体的里面创建,局部内部类不能有访问说明符,因为它不是外围类的一部分,但是它可以访问当前代码块内的常量以及此外围类的所有成员。

     

    interface Counter {
        int next();
    }
    
    public class LocalInnerClass {
        private int count = 0;
        Counter getCounter(final String name) {
            class LocalCounter implements Counter {
                public LocalCounter() {
                    System.out.println("LocalCounter()");
                }
                public int next() {
                    System.out.print(name);
                    return count++;
                }
            }
            return new LocalCounter();
        }
        Counter getCounter2(final String name) {
            return new Counter() {
                {
                    System.out.println("Counter()");
                }
                public int next() {
                    System.out.print(name);
                    return count++;
                }
            };
        }
        public static void main(String[] args) {
            LocalInnerClass lic = new LocalInnerClass();
            Counter
                    c1 = lic.getCounter("Local inner "),
                    c2 = lic.getCounter2("Anonymous inner ");
            for(int i = 0; i<5; i++)
                System.out.println(c1.next());
            for(int i = 0; i<5; i++)
                System.out.println(c2.next());
        }
    }

     

    输出结果为:

    LocalCounter()

    Counter()

    Local inner 0

    Local inner 1

    Local inner 2

    Local inner 3

    Local inner 4

    Anonymous inner 5

    Anonymous inner 6

    Anonymous inner 7

    Anonymous inner 8

    Anonymous inner 9

     

    10.12 内部类标识符

     

      由于每个类都会产生一个.class文件,其中包含了如何创建该类型的对象的全部信息。内部类也必须生成一个.class文件以包含他们的Class对象信息,这些类文件的命名有严格的规则:外围类的名字加上“$”再加上内部类的名字,例如LocalInnerClass.java生成的.class文件包括:

    Counter.class
    
    LocalInnerClass$1.class
    
    LocalInnerClass$1LocalCounter.class
    
    LocalInnerClass.class

      如果内部类是匿名的,编译器会简单产生一个数字作为其标识符,如果内部类是嵌套在别的内部类之中,只需直接将他们的名字加在其外围类标识符与“$”后面。

  • 相关阅读:
    每日日报31
    每日日报30
    每日日报29
    《精益软件开发管理之道》阅读笔记03
    每日日报28
    ip地址访问vue项目
    eslint prettier vetur eslint
    线上环境去除console
    vue 多环境打包
    2申请高德地图key 初始化地图
  • 原文地址:https://www.cnblogs.com/parable/p/11517671.html
Copyright © 2020-2023  润新知