第5章 继承

继承的基本思想:基于已经有的类创建新的类。

类,超类,子类

继承关系的明显特征:is-a(是)

定义子类

格式:子类名 extends 父类名(若无extends,默认继承父类Object)

关键字extends 表明正在构造的新类派生于一个已存在的类。
已存在的类:超类(superclass),基类(base class),父类(parent class)
新类:子类(subclass),派生类(derived class),孩子类(child class)

子类将继承父类成员,但不能直接访问父类private成员,子类还可以进行扩展(增加新的成员变量和方法)和特殊化(覆盖:重新定义父类中已有的方法),因此子类比超类拥有的功能更多。

覆盖方法:

子类对父类已有方法的重新定义:子类中的方法应与父类中被覆盖的方法有完全相同的参数列表,返回值且访问权限不能更严格。

当我们需要调用超类中被覆盖的原方法,可以使用super
super.getsalary();

子类构造器:

  1. 在子类的构造方法中,不能直接访问父类私有成员,因此必须调用父类构造器初始化这些成员变量,使用super(参数)调用父类的含参构造方法,且super必须是第一句
  2. 如果子类的构造方法中,没有使用super调用父类的构造方法和this调用重载的其他构造方法,则在创建子类对象时,系统默认先调用父类的无参构造方法,然后执行子类的构造方法。(若父类没有午餐构造方法,且子类构造方法中没有调用父类其他构造方法,就会发生编译报错)
  3. super()和this()不能同时出现

继承层次:

Java——>单继承,多重继承(创建对象时,先调用父类构造方法初始化,递归调用层次从上到下)
由一个公共超类派生出来的所有类的集合称为继承层次
在继承层次中,从某个特定的类到其祖先的路径称为该类的继承链。

多态:

多态(Polymorphism)面向对象三大特征之一,它的前提是封装形成独立体,独立体之间存在继承关系,从而产生多态机制。

一个引用变量可以引用多种实际类型对象的现象
(可以引用这个类和该类所有子类对象)

在运行时能够自动地选择适当的方法(执行过程中根据引用变量实际引用的对象类型调用相应的方法)称为动态绑定
优点:无需对现存代码进行修改即可对程序进行扩展。

父类引用变量引用子类对象
1.规则:沿着继承层次,从上往下,子类对象当作父类对象使用
2.转换时机:赋值,方法调用(参数传递)

阻止继承的方式:final类和方法

  • final标记的类不能被继承
  • final标记的方法不能被覆盖
  • final标记的变量是常量,只能赋值一次(final成员变量必须在定义时赋值或在构造方法中赋值,才能使用)

强制类型转换:

在 java 中允许这样的两种语法出现,一种是向上转型(Upcasting),一种是向下转型(Downcasting),向上转型是指子类型转换为父类型,又被称为自动类型转换,向下转型是指父类型转换为子类型,又被称为强制类型转换。
只有在访问子类型中特有数据的时候,需要先进行向下转型。

instanceof :引用变量 instanceof 类名
判断对象是否是某一类或该类的子类

  • 只能在继承层次内进行强制类型转换
  • 在将超类强制转化为子类前,应使用instanceof进行检查
  • 在进行任何向下转型的操作之前,都要使用 instanceof 进行判断,

在这里插入图片描述一般来说,最好尽量少用强制类型转换和instanceof运算符
在这里插入图片描述

抽象类

对于具有一般性的祖先类,可以将其声明为抽象类,只将它作为派生其他类的基类。 采用 abstract 关键字定义。

抽象类:

  • 不包含任何方法定义的方法称为抽象方法
  • 任何包含抽象方法的类必须被声明为抽象类
  • 抽象类不能被 final 修饰
  • 抽象方法不能被 final 修饰,因为抽象方法就是被子类实现的。
  • 不能生成抽象类的对象,但可以定义抽象类的引用变量,用来引用非抽象子类
  • 扩展抽象类可以有两种选择,一种是在子类中保留抽象类中的部分或所有抽象方法仍未定义,这样就必须把子类也声明为抽象类,另一种方法就是定义全部方法,子类就不是抽象的了(抽象类的子类必须覆盖所有的抽象方法,才能生成对象,否则仍是抽象类)
  • 抽象类还可以包含字段和具体方法

访问控制

访问控制修饰符:
用来控制类,成员变量,方法和构造方法的访问权

  • public:所有类可见
  • protected:对子类和本包可见(继承访问权限)
  • 缺省:对本包可见
  • private:本类可见

其中成员变量,方法和构造方法可以使用这四种修饰符,一般类使用public和缺省修饰符。

Object类

Object类是Java中所有类的始祖,如果没有明确指出父类,Object被认为是这个类的超类。

可以使用Object类型的变量引用任何类型的对象,但这种引用变量只能作为各种值的一个泛型容器。

equals方法

  • 检测一个对象是否等于另一个对象(通过比较是否有相同的引用)
  • 可在类中重新定义该方法,以实现预期操作
    在这里插入图片描述

为了防备成员变量的对象引用为null值的情况(如上图name,hireDay),需要使用Object.equals方法,如果两个参数都为null,Object.equals(a,b)调用将返回true
,如果其中一个为null,返回false,若两个参数都不为null,则调用a.equals(b).

在这里插入图片描述

在子类中定义equals方法时,首先调用父类的equals,如果检测失败,对象不可能相等,如果父类字段都相等再比较子类中的实例字段。如上图示。

Java语言规范要求equals方法具有以下特性
在这里插入图片描述编写一个完美的equals方法的建议:
1.显示参数命名为otherObject,稍后需要将它强制转换成另一个名为other的变量
2.检测this和otherObject是否相等

if(this == otherObject) return true;

3.检测otherObject是否为null,如果为null,返回false(必要)

if(otherObject==null) return false;

4.比较this与otherObject的类,如果equals的语义可以在子类中改变,就使用getClass检测

if(getClass()!=otherObject.getClass()) return false;

如果所有子类都具有相同的相等性语义,可以使用instanceof检测

if(!(otherObject instanceof ClassName)) return false;

5.将otherObject强制转换为相应类类型的变量

ClassName other=(CLassName) otherObject

6.现在根据相等性概念的要求来比较字段。使用==比较基本类型字段,使用Objects.equals(a,b)来比较对象字段。如果所有字段都匹配,返回true,否则返回false

PS:如果在子类中重新定义equals,就要在其中包含一个super.equals(other)调用。

hashCode方法

  • 散列码(hash code)是由对象导出的一个整型值。
  • Object类默认的散列码为对象的存储地址。
  • String类使用以下算法计算散列码:
int hash=0;
for(int i=0;i<length();++i)
hash=31*hash+charAt(i);
  • 如果重新定义了equals方法,则必须重新定义hashCode方法,定义必须保证:若x.equals(y)==true,则x.hashCode()==y.hashCode
  • 需要组合多个散列值时,可以调用Objects.hash并提供所有这些参数
public int hashCode()
{
	return Objects.hash(name,salary,hireDay);
}
  • 数组类型的字段,可以使用静态的Arrays.hashCode计算数组的散列码,这个散列码由数组元素的散列码组成。
  • null安全的方法:Objects.hashCode,若其参数为null,返回0,否则返回对参数调用a.hashCode()的结果。

toString方法

  • 返回表示对象值的一个字符串
  • 一般的类实现为:类名[成员变量值]
  • 获取类名时,最好通过调用getClass().getName()获得类名的字符串,而不要将类名硬编码写到toString方法中
  • 只要对象与一个字符通过操作符“+”连接起来,Java编译器就会自动调用toString方法来获得这个对象的字符串描述。
  • Object类中定义的toString方法,可以打印对象的类名和散列码。
  • 数组继承了Object类的toString方法,所以若需要打印出数组元素可调用Arrays.toString,打印多维数组:Arrays.deepToString
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值