美文网首页Java学习笔记我爱编程Java学习笔记
读书笔记 | 《Think in Java》Ⅶ 复用类

读书笔记 | 《Think in Java》Ⅶ 复用类

作者: 寒食君 | 来源:发表于2018-04-16 00:31 被阅读30次
    信仰牌咖啡

    Ⅶ 复用类

    复用代码是Java众多引人注目的功能之一,Java的代码复用都是围绕类来展开的。所以很多时候,不需要重复去造轮子,而是可以直接调试使用他人写好的类库框架。当然,在现阶段,自己动手才是最好的学习方式。

    Java的代码复用方式主要有两种:

    1. 组合:在新的类中产生现有类的对象。
    2. 继承:通过现有的类型来创建新类。

    7.1 组合语法

    • 在前文关于初始化的部分中提到,Java类钟域为基本数据类型时能自动初始化某默认值(具体可以去查表),对象引用默认会被初始化为null。
      其实编译器并不是简单地为每一个引用都创建默认对象,因为这样的好处是可以减轻某些不必要的负担与开销。如果明确想要初始化这些引用,可以在以下几个位置进行:
    1. 在定义对象的地方,这将在调用构造器之前被初始化。
    class Wheel{
      private String type;
      Wheel{}{
      }
    
    //
    Class Car{
      private Wheel w=new Wheel();
    }
    }
    
    1. 在类的构造器中。
    class Wheel{
      private String type;
      Wheel{}{
      }
    
    //
    Class Car{
      private Wheel w;
      Car (){
        this.w=new Wheel();
      }
    `}
    }
    
    1. 在需要使用到这些对象时,这种被称为惰性初始化。

    7.2 继承语法

    • 在子类中完全可以使用基类中的方法并对它进行修改。假如基类中有个方法叫take(),你想要在子类的take()方法中不对基类方法进行修改,那么不能直接在子类的take()中调用take(),因为这会产生递归。而是需要在子类的take()super.take()

    7.3 代理

    • 代理是介于继承和组合中间的一种方式,Java没有对其直接支持。代理是什么意思?
      比如我们把一个成员对象置于所要构建的新类中(组合),但是需要在新类中暴露这个对象的所有方法(继承)(不适合使用继承的另一个原因是也往往违背了is-a关系)。

    • 实际用法是需要在新类中再次对这个对象的方法进行封装描述,这有点麻烦,但是好处是使用代理时可以获得多个对象得不同能力,而且也可以取其子集。

    7.4 结合使用组合和继承

    • 有时记得进行必要的清理,在清理时注意对基类清理方法和对成员对象清理方法的调用顺序,其顺序应该和生成对象的顺序相反。

    • 大多数情况下,清理不是问题,仅仅交给垃圾回收器来做就行了。但有必要时,需要我们手动处理。最好的办法是除内存以外,不要依赖垃圾回收器做其他清理工作。当需要进行必要的清理时,编写你自己的方法,但不要使用前文提到的finalize()

    • 相较于继承,组合方式往往更常用,尽管在学习OOP时,我们强调继承这一概念。那么到底什么情况下使用继承?一个比较好的方法是,考虑在工程中,是否有需要从新类向基类进行向上转型。如果必须向上转型,那么继承是必要的。

    7.7 向上转型

    • 向上转型是一个专用的类型向通用类型转换,所以总是很安全的。在向上转型的过程中,类接口中可能发生的情况是丢失方法。

    7.8 final关键字

    在不同的上下文环境中,final有着细微的区别,它通常是来表示“不可改变的”,当然也存在着特殊的情况。

    final一般有三种使用场景:数据、方法、类。

    7.8.1 数据
    • 编译期常量,是使用final修饰的基本数据类型,在定义时必须进行赋值。这是一种使数据恒定不变的方式。

    • 在使用 final修饰一个引用时,final使引用固定地指向一个对象,但是这个对象本身是可以修改的。

    • final修饰的数据并不代表我们在编译期就可以知道它的值。比如:

    static Random rand=new Random(10);
    final int a=rand.nextInt(10);
    
    • 值得一提的是,还可以用final来修饰方法参数,当一个参数被final修饰后,意味着在这个方法中,无法改变参数引用所指向的对象了。
    7.8.2 方法
    • final方法的用处有两个:
    1. 锁定方法,防止在继承类中被重写。(这是出于一些情况的设计,需要确保在继承中此被继承方法的功能不变)
    2. 过去使用final修饰方法可能是出于效率的考量,但是现在并不是很需要。(如果将一个方法指明为final,就是同意编译器将针对该方法的所有调用都转为内嵌调用。在后续版本中这样效率反而降低,已经不需要了。)
    • 所有的private方法其实都是隐式地被指定为final。如果你试图去覆盖一个private方法,似乎是奏效的,因为编译器没有报错,但实际是不对的,可以编写代码来测试。这里就不演示了。
      覆盖只有在子类中某方法是基类的接口的一部分时才会出现。private修饰的方法,不会是基类接口的一部分。
    7.8.3 类
    • 使用final修饰的类无法被继承。当然,其中的方法也无法被覆盖。

    7.10 总结

    • 继承和组合都能从现有类型生成新类型。组合一般是将现有类型作为新类型底层实现的一部分来加以复用,继承复用的是接口。

    • 子类拥有父类接口,所以可以向上转型,这对多态来说至关重要。


    扫一扫,关注公众号

    小白的成长探索之路。

    相关文章

      网友评论

      • IT人故事会:老铁下次注意格式啊,不太清晰,给点建议对于新手需要的是注释啊
        寒食君:@IT人故事会 嗯嗯 其实不建议纯新手看这个:flushed:

      本文标题:读书笔记 | 《Think in Java》Ⅶ 复用类

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