【8】Head First Java 学习笔记

HeadFirst Java

本人有C语言基础,通过阅读Java廖雪峰网站,简单速成了java,但对其中一些入门概念有所疏漏,阅读本书以弥补。

第一章 Java入门
第二章 面向对象
第三章 变量
第四章 方法操作实例变量
第五章 程序实战
第六章 Java函数库
第七章 继承与多态
第八章 深入多态


抽象的类

上一章讲到Animal类,但考虑一个问题 Animal animal = new Animal();非常不合理,Animal是啥样子?什么颜色、大小、种类。
——尝试创建 Animal类的对象 是不合情理的

防止Animal类被初始化

标记类为抽象的:abstract class Animal
1.此类不能创造任何类型的实例(创造该类的对象),不能被”new“出来
2.可以用这种抽象类型作为引用类型

设计好继承结构后,要决定哪些类抽象,哪些类具体,具体的类可以初始化为对象,创造出对象
实例化抽象类在编译器会报错!
抽象类只用于被继承,没有其他用途、值、目的

抽象的方法

意义:没有共同程序代码,但声明了共同协议,为标记多态而存在!所有子型都有该方法~
比如说,vet类中giveEat方法Animal作为参数,可以接入所有的子类,那么可以直接调用a.eat()。而不用为所有动物在vet中写giveEat方法。

抽象的方法没有实体——为什么要抽象这个方法,因为没有通用的行为!
public abstract void eat(); ——没有一样的吃法~
非抽象类中不能有抽象方法!

必须实现所有抽象的方法

原则:抽象的类必须被继承,抽象的方法必须被覆盖
——具体的第一个子类 必须实现抽象的方法,即覆盖抽象的方法(相同的名称、参数、相容返回类型创建非抽象方法)

抽象子类 来实现父类的抽象方法也可以

多态的使用

自行创建一个Dog和Cat的专用List,那要写俩个DogList类和CatList类,不需要的,可以通过多态!

public class MyAnimalList {
	private **Animal**[] animals = new **Animal**[5];//这不是创建Anmial对象,只是个数组对象,用来保存Animal子类对象
	private int index;
	public void add(**Animal** a) {
		if (index < animals.length) {
			animals[index] = a;
			index++;
		}
	}

Object

  • 多态的使用
    那不是Animal怎么实现多态,是否有万用类呢?——Object
    ArrayList类可以储存任何类!
    ∵在Java中,所有类都是从Object(对象)这个类继承出来的,这由编译器实现,也就是说,所有我们没定义父类的类,都是Object的子类!
    结论:有了Object,我们可以创造出可以处理任何类的自定义类。

  • Object有啥?
    boolean equals() 对象是否相等?
    Class getClass() 对象根据哪个类模板初始化的
    int hashCode() 对象的Hash码
    String toString() 对象的名称和一串字符

Object类是具体的类——有时候需要一个通用对象,常用于线程同步化
作用:多态 + 提供通用方法
为什么不把所有参数设置为Object?
比如你用Object代替Animal,这时你传入非Animal子类的对象,岂不是不合理!
当然编译器也会报错。编译器保证:当某个对象是Object类型引用时,会把它当作Object实例,只能使用Object的方法。`Object o = new Ferrai();.o.goFast();//这是非法的,o被初始化为Object实例!
为什么要这样保证?——因为编译的类型安全检查机制,对象必须执行合理的行为。Object虽然是万能类,但应该只使用一些通用方法。

  • 使用Object类型的多态引用的代价
ArrayList<Object> list = new ArrayList<Object>();
list.add(new Dog());
Dog a = list.get(0);//报错!get会返回Object类,编译器无法确认他是Dog,而引用类型和对象的类型是必须一致或引用类型为父
list.get(0).bark();//报错!编译器只知道引用类型的方法!

如何转换回原类型?
if (o instanceof Dog) Dog d = (Dog) o;
在这里插入图片描述

修改Class层次

通过前文,我们知道JAVA 注重引用变量的类型!类的公有方法 相当于 合约。
对于Dog,类Canine、Animal、Object中的元素都是合约的部分
但如果你希望Dog有宠物等行为方法,要怎么设计呢?
我想到是 两种父类,但这有致命方块问题P223,不确定继承来自哪个类的覆写方法。
——接口解决多重继承问题,而不产生致命方块!
如何解决的:方法全部设为abstract,子类必须覆写方法。 100%的抽象类
接口的定义:public interface Pet{}
接口的实现:public class Dog extends Animal implements Pet{}
接口的意义:多态!类可以继承自父类,也可实现多个接口
在这里插入图片描述

设计:类、子类、抽象类、接口

类:新类无法通过其他类IS-A测试,创建新类 Robot
子类:某类的具体版本,以覆盖或增加新方法来继承现有类 Cat、Dog
抽象类:定义一群子类的模板,又不希望该类被程序员初始化 Animal
接口:定义类扮演的角色 Pet

补充

  • 子类覆写方法,在父类基础上额外加
abstract class Report {
	void runReport(){
	}
}
class sonReport extends Report {
	void runReport(){
		super.runReport();
		//其他
	}
}
  • 抽象的方法没有内容,声明以分号结束
上一篇:07 流量回放实现自动化回归测试


下一篇:ansible下playbook安装httpd