Java面向对象之继承
Posted Guarding and trust
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java面向对象之继承相关的知识,希望对你有一定的参考价值。
Java三大特性之继承
本篇内容
1.继承的含义
2.继承的运用
3.顶级父类:Object
4.小结
1.继承的含义
继承是Java三大特性之一。何为继承?其实继承在我们现实生活中类似于父与子,在一个家庭中,有继承家产这一家规,而继承家产一般是儿子继承的。那么,在Java中是如何体现继承的呢?其实在Java中父与子关系的术语是,一个是父类/超类/基类,另一个是子类/派生类,它们之间用到关键字extends。而继承的最作用就是:能让我们的代码进行重用,同时还能对现有类进行功能上的扩展!
2. 继承的运用
- 刚才已经简单介绍了何为继承,不过有可能还是不太懂,接下来我们来以实例来实现继承的效果,但是在使用继承之前,我们先来个不继承的例子。
- 无继承的例子
public class teacher{ //创建一个教师类
//属性
public String name;
public String school;
//方法
public void run(){
System.out.println(this.name + "在跑步");
}
public void giveLesson(){
System.out.println(this.name + "在" + this.school + "上课");
}
}
public class Worker{ //工人类
//属性
public String name;
public String factory;
//方法
public void run(){
System.out.println(this.name + "在跑步");
}
public void work(){
System.out.println(this.name + "在" + this.factory + "工作");
}
}
- 我们可以看到上面两个类有重复代码的地方,是否还记得刚才说的继承的作用吗?继承就是为了代码可重用性!减少代码的冗繁程度!在上面两个类中,教师类和工人类都属于人类,我们把他们的共同点定义在人类中。那么人类就是这两个类的父类,而教师类和工人类是子类。请看以下代码:
- 使用继承的特性编写上面的例子:
// 人类是父类,存放的是一些更加通用的属性及方法
public class Human{
public String name;
public void run(){
System.out.println(this.name + "在跑步");
}
}
// 教师类继承于人类,所以自动拥有了名字和跑步的方法
public class Teacher extends Human{ //继承用关键字extends
public String school;
public void giveLesson(){
System.out.println(this.name + "在" + this.school + "上课");
}
}
// 工人类继承于人类,所以也自动拥有了名字和跑步的方法
public class Worker extends Human{ //继承用关键字extends
public String factory;
public void work(){
System.out.println(this.name + "在" + this.factory + "工作");
}
}
- 使用 extends 关键字实现类之间的继承关系,查看上述代码,继承父类后代码能够得到复用,子类中只要写一些特别的属性及方法就可以。在使用的时候,一般情况下子类是可以调用父类的属性和方法,由此父类是一般是通用属性和方法,子类在父类的基础上可进行扩展。【注意:虽然上面的示例中我们成功地重用了代码,但是,我们并不能因为少写几句代码而去套用继承的实现。】
3. 顶级父类:Object
在 Java 中创建类,如果没有声明继承关系、父类,编译器会自动添加 Object 为其父类。因此,所有的 Java 类直接或者间接地继承了 Object 类,自动拥有了其所有属性(没有属性)和方法。其中Object常用的一些方法有以下几种:
toString()
【String toString() 】方法调用后返回该调用对象的字符串形式,通常用于字符串转换、字符串日志输出打印中。示例代码如下:
public class A{} // 默认实现
public class B{
@Override public String toString(){
return "this is B class.";
}
}
// 入口测试
System.out.println(new A()); // A@1b6d3586
System.out.println(new B()); // this is B class.
- 可以看到:
a.打印会自动调用对象的 toString 方法
b.默认的对象会转换为一个带类名和内存地址的字符串
c.可以重写 toString 方法,返回自定义字符串内容
d.一般编写的类需要打印到控制台、或者以文本方式输出的时候,我们需要手动编写 toString 方法。
equals()
- boolean equals(Object) 方法用于比较两个对象是否相等。示例代码如下:
public class Date{
//属性
public int year;
public int month;
public int day;
//方法
public Date(int year, int month, int day){
this.year = year;
this.month = month;
this.day = day;
}
}
public class Test{ //入口测试
public static void main(String[] args) {
//对象实例化
Date d1 = new Date(2020, 11, 11);
Date d2 = new Date(2020, 11, 11);
//调用成员方法
System.out.println(d1 == d2); // false
System.out.println(d1.equals(d2)); // false
}
}
可以看到上述代码的输出都是 false ,原因很简单:
- == 表示两个对象或者值是否完全相等,如果是对象则表示引用的对象、地址完全一样
- equals 表示两个对象是否相同,两个对象进行比较时,默认情况下和 == 效果相当
getClass()
Class<?> getClass() 方法用于返回任意对象的类,即对象运行时类:
A a = new A();
System.out.println(a.getClass()); // class A
System.out.println(a.getClass().getName()); // A
hashCode()
int hashCode() 方法返回一个整数即对象的哈希码值,是一个 Native 本地方法,该方法在涉及到数据相关操作时非常重要,一旦类的 equals 方法被重写,那么对象的 hashCode 方法也尽量需要实现重写。
哈希值有个重要的特点:相同类型的两个对象如果相同,那么他们的哈希值也应该一样;相反如果两个对象不一样,那么其哈希值也应该不一样;反之,哈希值相同不能代表两个对象一样!所以,哈希值只能用于判断不相等,而不能用于判断对象的相等。
我们发现,打印一个没有重写 toString 方法的对象时,输出的内容是这种格式: A@6d666d9c 实际上也就是 包名.类名@数字 ,那么这个数字是什么呢?查看 toString 方法源码:
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
- 在上面的源码可以很清晰的知道打印的结果是哈希值!!
其他方法
其他方法包括 clone() 和 finalize() 都是本地方法( Native ),不推荐直接使用;另外 notfiy()/notifyAll()/wait() 这些方法用于多线程处理,因为有了新的 java.util.concurrent 包的引入,已经不推荐使用这些方法。
4.小结
以上就是继承的基本内容,看着知识点不是很多,但是要真正消化是需要多加练习的。最主要的是要知道什么时候使用继承,换句话说继承不是用的越多越好。下面来总结一下使用继承的一些注意事项。
在 Java 中使用继承需要注意一些事项:
(1)单一继承原则:子类只允许继承一个父类,不能有多继承
(2)单方向继承原则:只允许子类获得父类的非私有成员
(3)父类 private 私有特征子类不能继承!只有 public/protected 属性方法可以被子类访问
(4)所有类的默认父类均为 Object ,因此都具有 Object 的一些方法,比如 【equals()】/【toString()】所有类默认情况下继承自 Object 父类,因此继承自 Object 类不需要显式地写出来,所以下面的类 A 默认会继承 Object 类:
// 其他类
public class A{}
public class B extends A{}
可以判断上面类的一个继承关系:
以上是关于Java面向对象之继承的主要内容,如果未能解决你的问题,请参考以下文章