概述
继承性
继承(Inheritance)是面向对象编程的三大特征之一,它让我们更加容易实现对于已有类的扩展、更加容易实现对于现实世界的建模。
继承及其作用
继承让我们更加容易实现类的扩展。 比如,我们定义了人类,再定义Boy类就只需要扩展人类即可。实现了代码的重用,不用再重新发明轮子。从英文字面意思理解,extends的意思是“扩展”。子类是父类的扩展。现实世界中的继承无处不在。
继承使用要点
- 父类也称作超类、基类。子类:派生类等。
- Java中只有单继承,没有像C++那样的多继承。多继承会引起混乱,使得继承链过于复杂,系统难于维护。
- 子类继承父类,可以得到父类的全部属性和方法 (除了父类的构造方法),但不见得可以直接访问(比如,父类私有的属性和方法)。
- 如果定义一个类时,没有调用extends,则它的父类是:java.lang.Object。
Object类
Object类是所有Java类的根基类,也就意味着所有的Java对象都拥有Object类的属性和方法。如果在类的声明中未使用extends关键字指明其父类,则默认继承Object类。
面试题目:请你写出Object类的6个方法
方法摘要 | |
---|---|
boolean | equals(Object obj) 指示其他某个对象是否与此对象“相等”。 |
Class<?> | getClass() 返回此 Object 的运行时类。 |
int | hashCode() 返回该对象的哈希码值。 |
void | notify() 唤醒在此对象监视器上等待的单个线程。 |
void | notifyAll() 唤醒在此对象监视器上等待的所有线程。 |
String | toString() 返回该对象的字符串表示。 |
void | wait() 在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。 |
void | wait(long timeout) 在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量前,导致当前线程等待。 |
void | wait(long timeout, int nanos) 在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量前,导致当前线程等待。 |
以上方法是Object类的所有方法吗?不是 是Object类所有的public方法。 除此之外可能还有private、protected、默认的方法
方法摘要 | |
---|---|
protected Object | clone() 创建并返回此对象的一个副本。 |
protected void | finalize() 当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。 |
toString()方法
toString()的作用是将一个对象转换为字符串并返回。Object类的toString()方法会返回getClass().getName()+"@"+Integer.toHexString(hashCode());,其含义是类的完整路径+“@”+十六进制的哈希码。
System.out的println()方法只能在控制台上输出字符串,当用这种方法输出对象时,实际上输出的是Object类中的toString()方法返回值
==和equals方法
“==”代表比较双方是否相同。如果是基本类型则表示值相等,如果是引用类型则表示地址相等即是同一个对象。
Object类中定义有:public boolean equals(Object obj)方法,提供定义“对象内容相等”的逻辑。比如,判断两个Dog是否是一个Dog,要求color、age、nickName等所有属性都相同。
Object 的 equals 方法默认就是比较两个对象的hashcode,是同一个对象的引用时返回 true 否则返回 false。显然,这无法满足子类的要求,可根据要求重写equals方法。
重写equals方法
public class Animal {
String color;
private int age;
public boolean equals(Object obj) {
Animal other = (Animal) obj;
//如果参数是null、,直接返回false
if(obj == null){
return false;
}
//如果两个变量指向同一个空间,直接返回true
if(this == obj ){
return true;
}
if(this.color.equals(other.color) && this.age == other.age){
return true;
}else{
return false;
}
}
}
public class Dog extends Animal {
private String nickName;
private String type;
public boolean equals(Object obj) {
Dog other = (Dog) obj;
boolean flag = super.equals(obj);
if (!flag) {
return false;
} else {
//如果Animal的equals返回true,需要再比较nickName、type
if (this.nickName.equals(other.nickName)
&& this.type.equals(other.type)) {
return true;
} else {
return false;
}
}
}
}
继承情况下构造方法的调用过程
继承条件下构造方法的执行顺序
- 构造方法的第一条语句默认是super(),含义是调用父类无参数的构造方法
- 构造方法的第一条语句可以显式的指定为父类的有参数构造方法:super(…)
- 构造方法的第一条语句可以显式的指定为当前类的构造方法:this(…)
注意事项 - 每个类最好要提供无参数的构造方法
- 构造方法的第一条语句可以是通过super或者this调用构造方法,须是第一条语句
- 构造方法中不能同时使用super和this调用构造方法,并不是说不能同时出现this和super
super关键字
super“可以看做”是直接父类对象的引用。每一个子类对象都会有一个super引用指向其直接父类对象。
使用super可以
1) 调用成员变量 super.color
2) 调用成员方法 super.introduce();
3) 调用构造方法 super(color,age);
注意
1) 使用super调用普通方法,语句没有位置限制,可以在子类中随便调用。
2) 在一个类中,若是构造方法的第一行代码没有显式的调用super(…)或者this(…);那么Java默认都会调用super(),含义是调用父类的无参数构造方法。这里的super()可以省略。
最后
以上就是沉默柚子为你收集整理的面向对象编程------继承的全部内容,希望文章能够帮你解决面向对象编程------继承所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复