zoukankan      html  css  js  c++  java
  • 内部类3

    内部类的继承

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

    class WithInner{
        class Inner {
            
        }
    }
    /**
     * 内部类的继承
     */
    public class InheritInner extends WithInner.Inner{
        public InheritInner(WithInner wi){
            wi.super();
        }
        public static void main(String[] args) {
            WithInner a=new WithInner();
            InheritInner b=new InheritInner(a);
        }
    }

    可以看到, InheritInner 只继承自内部类,而不是外围类。但是当要生成一个构造器时,默认的构造器并不算好,而且不能只是传递一个指向外围类对象的引用。此外,必须在构造器内使用如下语法:
    enclosingClassReference. super():
    这样才提供了必要的引用,然后程序才能编译通过。

    内部类可以被覆盖吗?

    如果创建了一个内部类,然后继承其外围类并重新定义此内部类时,会发生什么呢?也就是说,内部类可以被覆盖吗?这看起来似乎是个很有用的思想,但是“覆盖”内部类就好像它是外围类的一一个方法,其实并不起什么作用:
    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();
        }
    }
    /**
     * 覆盖内部类10.10
     *
     */
    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
    默认的构造器是编译器自动生成的,这里是调用基类的默认构造器。你可能认为既然创建了BigEgg的对象,那么所使用的应该是“覆盖后”的Yolk版本,但从输出中可以看到实际情况并不是这样的。这个例子说明,当继承了某个外围类的时候,内部类并没有发生什么特别神奇的变化。这两个内部类是完全独立的两个实体,各自在自己的命名空间内。当然,明确地继承某个内部类也是可以的,就像这样
    public class BigEgg extends Egg{
        public class Yolk extends Egg.Yolk{
            public Yolk() {
                System.out.println("BigEgg.Yolk");
            }
        }
        public static void main(String[] args) {
            new BigEgg();
        }
    }

    局部内部类

    匿名内部类只用于实例初始化

    使用局部类而不是用匿名类的一个原因是,需要不至于一个该内部类的对象

     

    内部类标识符

    由于每个类都会产生一个.class文件,其中包含了如何创建该类型的对象的全部信息(此信息产生一个“meta-class" ,叫做Class对象), 你可能猜到了,内部类也必须生成一个.class文件以包含它们的Class对象信息。这些类文件的命名有严格的规则:外围类的名字,加上“$”,再加上内部类的名字。例如,LocalInnerClass.java生 成的.class文件包括:
          Counter .class
          LocalInnerciassS1.class
          Local InnerClass$lLocalCounter .classLocalInnerclass.class
          如果内部类是匿名的,编译器会简单地产生一一个数字作为其标识符。如果内部类是嵌套在别的内部类之中,只需直接将它们的名字加在其外围类标识符与“$”的后面。
          虽然这种命名格式简单而直接,但它还是很健壮的,足以应对绝大多数情况。因为这是Java的标准命名方式,所以产生的文件自动都是平台无关的。(注意,为了保证你的内部类能起作用,Java编译器会尽可能地转换它们。)
  • 相关阅读:
    Traits——信息输入界面
    Traits——安装/第一个界面
    opencv——如何安装opencv—python
    python——如何将列表中的元素全部取出来变成列表
    Pandas——循环路径下的文件将所有的txt文件进行合并
    股票交易
    良知?
    同源策略
    同步 异步 阻塞 非阻塞
    线程安全
  • 原文地址:https://www.cnblogs.com/QianYue111/p/10210400.html
Copyright © 2011-2022 走看看