第八章 复用

组合语法

初始化引用有四种方法:

  1. 当对象被定义时。这意味着它们总是在调用构造函数之前初始化。
  2. 在该类的构造函数中。
  3. 在实际使用对象之前。这通常称为延迟初始化。在对象创建开销大且不需要每次都创建对象的情况下,它可以减少开销。
  4. 使用实例初始化。

继承语法

初始化基类

Java 自动在派生类构造函数中插入对基类构造函数的调用。

构造从基类“向外”进行,因此基类在派生类构造函数能够访问它之前进行初始化。即使不为 Cartoon 创建构造函数,编译器也会为你合成一个无参数构造函数,调用基类构造函数。

先调用基类构造器,从最基类向外层层调用。

带参数的构造函数

对基类构造函数的调用必须是派生类构造函数中的第一个操作。

委托

Java不直接支持的第三种重用关系称为委托。这介于继承和组合之间,因为你将一个成员对象放在正在构建的类中(比如组合),但同时又在新类中公开来自成员对象的所有方法(比如继承)。

结合组合与继承

保证适当的清理

在清理方法 中,还必须注意基类和成员对象清理方法的调用顺序,以防一个子对象依赖于另一个子对象。首先,按与创建的相反顺序执行特定于类的所有清理工作。(一般来说,这要求基类元素仍然是可访问的。) 然后调用基类清理方法。

组合与继承的选择

当你想在新类中包含一个已有类的功能时,使用组合,而非继承。

当使用继承时,使用一个现有类并开发出它的新版本。通常这意味着使用一个通用类,并为了某个特殊需求将其特殊化。

是一个”的关系是用继承来表达的,而“有一个“的关系则用组合来表达。

protected

protected 也提供了包访问权限。

向上转型

继承图中派生类转型为基类是向上的,所以通常称作向上转型。因为是从一个更具体的类转化为一个更一般的类,所以向上转型永远是安全的。

再论组合和继承

尽量少使用继承。

使用继承前,问一问“我需要向上转型吗?”

final关键字

final 数据

在 Java 中,编译时常量必须是基本类型,而且用关键字 final 修饰。

对于基本类型,final 使数值恒定不变,而对于对象引用,final 使引用恒定不变。一旦引用被初始化指向了某个对象,它就不能改为指向其他对象。但是,对象本身是可以修改的,Java 没有提供将任意对象设为常量的方法。这一限制同样适用数组,数组也是对象。

不能因为某数据被 final 修饰就认为在编译时可以知道它的值。可以当值在运行时被初始化。

空白 final

必须在定义时或在每个构造器中执行 final 变量的赋值操作。这保证了 final 属性在使用前已经被初始化过。

final 参数

在参数列表中,将参数声明为 final 意味着在方法中不能改变参数指向的对象或基本变量。这个特性主要用于传递数据给匿名内部类。

final 方法

使用 final 方法的原因是:给方法上锁,防止子类通过覆写改变方法的行为。

final 和 private

如果一个方法是 private 的,它就不是基类接口的一部分。

但是如果你在派生类中以相同的命名创建了 public,protected 或包访问权限的方法,这些方法与基类中的方法没有联系,你没有覆写方法,只是在创建新的方法而已。由于 private 方法无法触及且能有效隐藏,除了把它看作类中的一部分,其他任何事物都不需要考虑到它。

final 类

final 类不能被继承。

类初始化和加载

构造器也是一个 static 方法尽管它的 static 关键字是隐式的。

类初始化顺序:

  1. 加载基类。不论是否创建了基类的对象,基类都会被加载。
  2. 根基类的 static 的初始化开始执行,接着是派生类,以此类推。
  3. 创建对象。首先,对象中的所有基本类型变量都被置为默认值,对象引用被设为 null —— 这是通过将对象内存设为二进制零值一举生成的。接着会调用基类的构造器。基类构造器和派生类构造器一样以相同的顺序经历相同的过程。当基类构造器完成后,实例变量按文本顺序初始化。最终,构造器的剩余部分被执行。

当开始设计一个系统时,记住程序开发是一个增量过程,正如人类学习。它依赖实验,你可以尽可能多做分析,然而在项目开始时仍然无法知道所有的答案。如果把项目视作一个有机的,进化着的生命去培养,而不是视为像摩天大楼一样快速见效,就能获得更多的成功和更迅速的反馈。继承和组合正是可以让你执行如此实验的面向对象编程中最基本的两个工具。

20190818 On Java8 第八章 复用的更多相关文章

  1. 20190906 On Java8 第十八章 字符串

    第十八章 字符串 +的重载与StringBuilder 用于String的+与+=是Java中仅有的两个重载过的操作符,Java不允许程序员重载任何其他的操作符.编译器自动引入了java.lang.S ...

  2. 《Entity Framework 6 Recipes》中文翻译系列 (42) ------ 第八章 POCO之使用POCO

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 第八章 POCO 对象不应该知道如何保存它们,加载它们或者过滤它们.这是软件开发中熟 ...

  3. Java8并发教程:Threads和Executors

    来之:ImportNew 欢迎阅读我的Java8并发教程的第一部分.这份指南将会以简单易懂的代码示例来教给你如何在Java8中进行并发编程.这是一系列教程中的第一部分.在接下来的15分钟,你将会学会如 ...

  4. Java8 十大新特性详解(转)

    本教程将Java8的新特新逐一列出,并将使用简单的代码示例来指导你如何使用默认接口方法,lambda表达式,方法引用以及多重Annotation,之后你将会学到最新的API上的改进,比如流,函数式接口 ...

  5. java5、java6、java7、java8的新特性

    Java5: 1.泛型 Generics:        引用泛型之后,允许指定集合里元素的类型,免去了强制类型转换,并且能在编译时刻进行类型检查的好处. Parameterized Type作为参数 ...

  6. [Effective Java]第八章 通用程序设计

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  7. 如何使用 Java8 实现观察者模式?(上)

    [编者按]本文作者是 BAE 系统公司的软件工程师 Justin Albano.在本篇文章中,作者通过在 Java8 环境下实现观察者模式的实例,进一步介绍了什么是观察者模式.专业化及其命名规则,供大 ...

  8. Java8之旅(七) - 函数式备忘录模式优化递归

    前言 在上一篇开始Java8之旅(六) -- 使用lambda实现Java的尾递归中,我们利用了函数的懒加载机制实现了栈帧的复用,成功的实现了Java版本的尾递归,然而尾递归的使用有一个重要的条件就是 ...

  9. 这可能是史上最好的 Java8 新特性 Stream 流教程

    本文翻译自 https://winterbe.com/posts/2014/07/31/java8-stream-tutorial-examples/ 作者: @Winterbe 欢迎关注个人微信公众 ...

随机推荐

  1. Spring事务管理之几种方式实现事务(转)

    一:事务认识 大家所了解的事务Transaction,它是一些列严密操作动作,要么都操作完成,要么都回滚撤销.Spring事务管理基于底层数据库本身的事务处理机制.数据库事务的基础,是掌握Spring ...

  2. P1828 香甜的黄油 (spfa)

    [题目描述] 农夫John知道每只奶牛都在各自喜欢的牧场(一个牧场不一定只有一头牛).给出各头牛在的牧场和牧场间的路线,找出使所有牛到达的路程和最短的牧场(他将把糖放在那). [题目链接] https ...

  3. 使用Kafka的一些简单介绍: 1集群 2原理 3 术语

    目录 第一节 Kafka 集群 Kafka 集群搭建 Kafka 集群快速搭建 第二节 集群管理工具 集群管理工具 集群 Issues 第三节 使用命令操纵集群 第四节 Kafka 术语说明 第五节 ...

  4. Java OO知识总结

    接着上一集    https://www.cnblogs.com/pdev/p/11288014.html       5. OO中的一些基本概念 继承 父类的非private方法自动被子类继承 cl ...

  5. 7、前端知识点--关于Array.from详解

    1.Array.from()方法就是将一个类数组对象 或 可遍历对象 或 可迭代对象 转换成一个真正的数组.浅拷贝的数组实例. 2.那么,什么是类数组对象呢?所谓类数组对象,最基本的要求就是具有len ...

  6. 从excel表中生成批量SQL

    excel表格中有许多数据,需要将数据导入数据库中,又不能一个一个手工录入,可以生成SQL,来批量操作.   ="insert into Log_loginUser (LogID, Logi ...

  7. apache重写规则简单理解

    1.前提:开启apache重写,并把httpd.conf里的相关的AllowOverride denied改为AllowOverride all 2.重写规则可写在项目根目录的.htaccess文件或 ...

  8. 小程序Page里的函数比app.js先执行的解决办法

    问题描述: 当我们初始化一个小程序时,默认文件 app.js 中有onLaunch函数, onLaunch: function () { console.log("onLaunch" ...

  9. OA是Office Automation

    OA是Office Automation OA是Office Automation OA是Office Automation

  10. csv导入数据

    1.关闭Neo4j服务器进程 2.删除graph.db数据库文件  /data/databases/  rm -rf graph.db 3.重新启动Neo4j服务器 4.数据导入import 5.wi ...