java编程思想第四版第七章总结
时间:2022-07-25
本文章向大家介绍java编程思想第四版第七章总结,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
1. 实现类的复用通常有两种方式
- 组合:在新的类中产生现有类的对象
- 继承:按照现有类的类型来创造新类
2. 一个特殊的方法toString()
- 在非基本类型的对象中, 都有toString()方法
- 当编译器需要一个String而你只有一个对象时, toString()方法会被自动调用
3. 父类方法的定义要求
- 所有的方法都是public的.
- 原因: 如果没有修饰符,则是包访问权限, 那么包以外的其他类继承了这个类, 依然不能访问这个父类的方法. 所以, 定义父类的公用方法需要时public的.
- 为了继承一般的规则是: 成员变量是private的, 方法是public的.
4. 基类初始化
- java会在子类中自动调用父类的构造器
- 父类如果没有默认构造器, 子类需要用super显示的调用父类的构造器. 而且调用父类构造器,必须是子类构造器要做的第一件事
- 基类的默认构造器, 也要显示的调用父类的有参构造器
5. 复用的第三种方式: 代理
- 代理: java并不直接支持他, 它是继承和组合之间的一种中庸之道.
- 无论我们使用的时组合, 还是继承. 都会暴露所有对象的成员方法
- 组合:在类中new一个对象, 然后该对象的所有成员方法在这个类中就都可以被使用。
- 继承:继承了父类, 那么父类的方法对这个子类来说, 更是完全可见的。
- 这两种方法都会完全暴掠被使用的那个类的成员方法, 而有的时候, 我们不希望这样, 不想父类或者被调用类的成员方法被暴露在外, 就可以采用代理的方式, 如下例:太空船需要一个控制模块 构造一个太空船, 可以使用组合或者继承。 我们这里使用继承的方式构造。 然而, SpaceShip并非一个真正的SpaceShipControls类型。太空船是太空船, 并不是太空控制器, 只是使用了太空控制器而已。更准确的说:SpaceShip包含SpaceShipControls。而且, 一旦继承, SpaceShipControls的所有方法都在SpaceShip中暴露了。这时我们可以使用代理方式来解决这个问题:
package net.mindview.reusing;
public class SpaceShipControls {
//velocity 速度
void up(int velocity){}
void down(int velocity){}
void left(int velocity){}
void right(int velocity){}
void forward(int velocity){}
void back(int velocity){}
void turboBoost(int velocity){} //发动
}
package net.mindview.reusing;
public class SpaceShipControls {
//velocity 速度
void up(int velocity){}
void down(int velocity){}
void left(int velocity){}
void right(int velocity){}
void forward(int velocity){}
void back(int velocity){}
void turboBoost(int velocity){} //发动
}
6. 如何选择组合和继承
- 组合通常是想在新类中使用现有类的功能而非他的接口。就是说,在新类中嵌入某个对象,让其实现所需要的功能,但新类的用户看到的只是为新类所定义的接口。而非锁嵌入对象的接口。为取得这个效果, 应该将现有类定义为private的。看下面的这个例子: 这里面, 显示的car的组成部分, 所以使用的是组合的方式。 而如果有一个“交通工具”和car是什么关系呢? 显然他们车不是交通工具组成的。car确实一类交通工具, 所以,交通工具和car应该是继承的关系。
package net.mindview.reusing;
class Engine {
public void start(){}
public void rev(){}
public void stop(){}
}
class Wheel {
public void inflate(int psi){}
}
class Window{
public void rollup(){}
public void rolldown(){}
}
class Door{
public Window window = new Window();
public void open(){}
public void close(){}
}
public class Car {
public Engine engine = new Engine();
public Wheel[] wheels = new Wheel[4];
public Door left = new Door(),right = new Door();
public Car(){
for(int i=0;i<4; i++){
wheels[i] = new Wheel();
}
}
public static void main(String[] args) {
Car car = new Car();
car.left.window.rollup();
car.wheels[0].inflate(72);
}
}
- 向上转型
package net.mindview.reusing;
/**
* 乐器
*/
class Instrument {
public void play(){}
//用乐器弹奏曲调
static void tune(Instrument i){
i.play();
}
}
//乐器的一种
public class Wind extends Instrument{
public static void main(String[] args) {
Wind wind = new Wind();
//使用wind弹奏曲调
Instrument.tune(wind);
}
}
- 上面的Instrument类中, 接收的Instrument的引用,在使用的时候, 我们可以将继承了Instrument的乐器传给tune方法。这称之为向上转型。
-
到底什么时候使用组合, 什么时候使用继承呢?
- 一个最清晰的判断就是, 问问自己,是否需要从新类向基类向上转型。如果需要转型, 那么就必须使用继承,否则就要好好想想了, 是否有使用集成的必要性。
7.final关键字
- final关键字的含义通常是“这是无法改变的
- 作用于成员变量, 表示该变量编译时不可变。
- 作用于成员变量, 和public static一起使用, 表示全局常量
- 成员变量是对象类型时使用final表示, 对象的引用不可改变。
- 空白final
- 所谓“空白final“指的是, 在定义final变量的时候不给他赋初始值, 而是在构造函数中为其赋值。这样就提供了更大的灵活性。使用方法如下所示:
package net.mindview.reusing;
class Poppet {
private int i;
Poppet(int i){
this.i = i;
}
}
public class BlankFinal {
//定义的时候赋初始值
private final int i = 0;
//空白final
private final int j;
//空白final引用
private final Poppet p;
public BlankFinal(){
j = 1;
p = new Poppet(1);
}
public BlankFinal(int x){
j = x;
p = new Poppet(x);
}
public static void main(String[] args) {
new BlankFinal();
new BlankFinal(4);
}
}
- 在参数列表中以声明的方式将参数指明为final
- 如果final作用的参数是对象,则表明在方法中无法更改参数引用所指向的对象。
- 如果final作用的是基本类型的参数, 则表示不可以改变传递过来的参数值。
package net.mindview.reusing;
class Gizmo{
public void spin() {}
}
//final作用于方法参数
public class FinalArguments {
//final作用于对象类型的方法参数
void with(final Gizmo g) {
//在这里不可以对传递过来个g重新指向新的引用
//g = new Gizmo();
}
void without(Gizmo g){
g = new Gizmo();
g.spin();
}
//final作用于基本类型的方法参数
void f(final int i) {
//在这里不可以对i重新赋值
//i++;
}
int g(final int i) {
return i+1;
}
public static void main(String[] args) {
FinalArguments bf = new FinalArguments();
bf.with(null);
bf.without(null);
}
}
- final方法
- 方法被定义final,则不可以被继承类修改。也就是确保方法的行为保持不变,不可被覆盖。
- final 类
- 当某各类被定义为final时,不可被继承
忠告:再设计类的时候, 将方法定义为final的,应该说是明智的。你可能会觉得,没人想要覆盖你的方法,但预见类是如何被复用是很困难的, 特别是对于一个通用类而言,更是如此。如果你将方法定义为final的, 可以防止其他程序员在项目中通过继承来复用你的类。
- JDK容器学习之Queue:ConcurrentLinkedQueue
- JDK容器学习之Queue: PriorityQueue
- React Native导航器之react-navigation使用
- Nginx 路由转发配置笔记
- React Native控件之ListView
- Java学习之深拷贝浅拷贝及对象拷贝的两种方式
- [周末课程]什么是“页面业务流程”分析思维导图?如何编写页面假JSON数据? &下一个前端组件“日历”
- Java并发学习之玩转线程池
- Java & PhantomJs 实现html输出图片
- 干货 | React Native实践之携程Moles框架
- Java并发学习之ThreadLocal使用及原理介绍
- ibeacon蓝牙技术简介
- Java并发学习之定时任务的几种玩法
- [视频直播]本周日先行者视频“React多级菜单
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- 为什么 Java 中 1000==1000 为 false ?
- 【java设计模式系列】2. 单例模式(Singleton)
- 跨域请求的解决方案
- 【排序】快速排序
- 因为BitMap,白白搭进去8台服务器...
- java所有的“锁”大总结,以后面试再也不怕遇到锁了
- 【Java8新特性】03 Stream流式数据处理
- 慎用JSON.stringify
- 【Java8新特性】04 详解Lambda表达式中Predicate Function Consumer Supplier函数式接口
- ubuntu下的进程控制系统————Supervisor
- 如何高效、快速、准确地完成ML任务,这4个AutoML库了解一下
- [译]如何用 Typescript 写一个完整的 Vue 应用程序
- Docker上手系列:Docker入门hello world
- 前端应该知道的 HTTP 知识
- React 学习笔记(基础篇)