美文网首页
第七章复用类

第七章复用类

作者: 浩林Leon | 来源:发表于2017-12-20 22:10 被阅读7次

    类的复用一般分为,组合和继承.

    7.1组合语法

    创建对象引用的方法一般有4种:
    1.在定义对象的地方.
    2.在类构造器中
    3.在正使用这对象之前,这种方法也成为惰性初始化.在生成对象不值得以及 不必每次都生成的情况下这种方法可以减少额外的负担.
    4.使用实例初始化.
    形式如下:

    public class Foo {
        //instance variable initializer 实例变量初始化器
        String s = "abc";
        //constructor 构造函数
        public Foo() {
            System.out.println("constructor called");
        }
        //static initializer   静态初始化器
        static {
            System.out.println("static initializer called");
        }
        //instance initializer 实例变量初始化器
        {
            System.out.println("instance initializer called");
        }
        public static void main(String[] args) {
            new Foo();
            new Foo();
        }
    }
    

    使用实例初始化的意义:优先构造函数,每次调用构造函数,里面的初始化都会执行.如果一个类有多个构造函数,有需求是在每个构造函数里面都需要进行初始化,可以利用实例初始化来减少重复的代码;在匿名内部类中可以进行初始化,因为这个类根本没有构造函数.

    7.2继承语法

    7.2.1基类初始化

    当创建了一个导出类(有继承基类的类)的时候,该对象已经包含了一个基类的子对象.该子对象和用基类直接创建的对象是一样的,区别在于基类子对象包装在对象内部,而直接创建的在外部.基类在导出类构造器可以访问他之前就已经初始化了.即使有时候导出类没有创建构造方法,编译器也会为你合成一个默认的造方法,该构造方法内部调用了基类造方法.
    采用默认构造器:不需要带参数.编译器可以为导出类创建基类.
     带参数的构造器:必须在每个构造器中显示的调用super()传递,或者不传参数.需要显示的调用基类的构造器.否则编译器无法编译通过.

    7.3代理

    代理是继承和组合之间的一种中庸之道.
    确保正确清理,如果需要清理对象,最好编写自己的清理方法,不要使用finalize()

    7.4名字屏蔽

    子类可以创建和基类相同名字的方法,而形参不同.不会被认为是override,此时子类还能正确的调用基类同名不同参数的方法.但是如果是子类需要重写 @override 基类的方法,那必须是方法名和参数完全一致.修饰词可以比基类的权限放宽,但是不能缩减.比如 基类 protected void fo(){…} ,子类可以 把放宽protected 为 public 或者保持protected.

    7.5protected关键字

    protected 表示,对于类用户他是private 的,但是对于子用户或者是同一个包内的类来说,他是可见的.尽管可以创建protected域,但是最好还是改成private ,protected用来控制类的继承范根权限.

    7.7向上转型(upcasting)

    因为在继承关系上面,一般是子类继承基类如下图所示:把wind强制转化成Instrument的实例进行处理,叫做向上转型.


    image.png

    向上转型是一个较专一的类转化为一个比较通用的类,所以的安全的.因为所有的子类都具备基类可以被继承的方法.向上转型的过程类接口唯一可能发生的事情是丢失方法,而不是获取新的方法.

    7.8final关键字

    java final关键字含义存在细微的差别,但是都是表示”这是无法改变的”.不做任何改变可能处于两种理由:”设计和效率”,由于这两个原因相差很远,所以有可能final会被勿用.
    可能用到final的3种情况: 类,方法,数据(变量)
    final数据:有数数据恒定不变是很有用的,比如:
    1.一个永不改变的编译时常量
    2.一个在运行时被初始化的值,而你不希望改变他.(初始化时)

    对于编译是常量,表示是在编译时进行计算式,减轻运行时的负担.在java中这写必须是基本类型,并且以final表示,在对这个常量定义是必须赋值.
    空白final
    java允许生成空白final ,即在定义的时候不初始化,但是必须在构造器执行完之前被初始化.也就以为着,可以在:
    1.构造器内  2.实例化块中 3.静态块中 (初始化)
    final参数
    在参数中设置final参数,意味在方法内部无法修改参数引用所指向的对象.但是可以修改该对象内部的值(调用该对象的方法).如果是基本类型数据,那么该基本类型数据是无法被修改的.
    final方法
    使用final方法的原因:
    1.把方法锁住,防止任何继承者修改.因为final方法是不能被重写(overriding)的.
    2.早期的虚拟机为了提高新能,会把含有final关键字的方法,把方法内部的调用都编译成内嵌调用.但是后来的编译器和虚拟机已经优化了这种处理效率问题.程序不需要考虑这个优化.
    final 和 private
    final类中所有的方法都会隐式的制定为final,由于无法覆盖final 方法,所以也就无法取用private方法,所有子类也无法重写(overriding)他.对于有一种情况:类有private 的同名方法,子类也可以定义一个 同名的方法.但是这其实不是重写(overriding),只是子类定义了一个同名的新方法而已,和基类的方法不会冲突.覆盖(重写/overriding)只有在基类暴露出来的接口(可以被子类访问)的情况下才会出现呢.
    出于某种原因,这个类永远不允许被继承

    7.8.4有关final的建议

    如果设计成final 方法,或者final 类时,需要考虑下是否会存在被复用的可能性.

    相关文章

      网友评论

          本文标题:第七章复用类

          本文链接:https://www.haomeiwen.com/subject/chinwxtx.html