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面向对象之继承的主要内容,如果未能解决你的问题,请参考以下文章

java面试准备之面向对象

Java学习面向对象之继承

java面向对象之继承

Java面向对象一(封装 继承 多态 类 对象 方法)

面向对象三大特征之二:继承

Java面向对象之继承