前言:
继承与多态是是 Java 在软件重用方面重要且功能强大的特征。假设要定义一个类,对圆、矩形和三角形建模。这些类有很多共同的特性。设计这些类来避免冗余并使系统更易于理解和易于维护的最好方式是什么?
答案就是使用继承。
因此我在此整理本章的重点与难点,以便于自己的复习与巩固。
1. 父类和子类:
在 Java 术语中,如果类 Cl 扩展自另一个类 C2, 那么就将 Cl 称为次类( subclass ), 将 C2 称为超类(superclass )。超类也称为父类 ( parent class) 或基类 ( baseclass), 次类又称为子类 ( child class)、扩展类 ( extended class) 或派生类(derivedclass)子类从它的父类中继承可访问的数据域和方法,还可以添加新数据域和新方法。
2.使用 super 关键字:
this 它是对调用对象的引用,关键字 super是指这个super 关键字所在的类的父类。关键字 super 可以用于两种途径:
1 ) 调用父类的构造方法。
2 ) 调用父类的方法。
注意:super和this的用法相似
this:代表本类的对象引用。
super:代表的父类内存 空间,而不是父类的引用。
子父类中同名的成员变量,这种情况开发中不用,因为父类一旦描述完成了属性,
子类直接使用就可以了。
3.调用父类的构造方法:
构造方法用于构建一个类的实例。不同于属性和普通方法,父类的构造方法不会被子类继承。它们只能使用关键字 super 从子类的构造方法中调用。
调用父类构造方法的语法是:
super()或者super(parameters);
语句 super() 调用父类的无参构造方法,而语句 super(arguments) 调用与参数匹配的父类的构造方法。语句 super() 和 super (arguments) 必须出现在子类构造方法的第一行,这是显式调用父类构造方法的唯一方式。
4.构造方法链:
构造方法可以调用重载的构造方法或父类的构造方法。如果它们都没有被显式地调用,编译器就会自动地将 superO 作为构造方法的第一条语句。例如:
在任何情况下,构造一个类的实例时,将会调用沿着继承链的所有父类的构造方法。当构造一个子类的对象时,子类构造方法会在完成自己的任务之前,首先调用它的父类的构造方法。如果父类继承自其他类,那么父类构造方法又会在完成自己的任务之前,调用它自己的父类的构造方法。这个过程持续到沿着这个继承体系结构的最后一个构造方法被调用为止。
这就是构造方法链(constructor chaining)。
5.调用父类的方法:
关键字 super 不仅可以引用父类的构造方法,也可以引用父类的方法。所用语法如下:
super.方法名(参数);
可以如下改写 Circle 类中的 pMntCircle()方法:
public void printCircle() {
System.out.println("The circle is created " +
super.getDateCreated() + " and the radius is " + radius);
}
在这种情况下,没有必要在 getDateCreated()前放置 super, 因为 getDateCreated 是
GeometHcObject 类中的一个方法并被 Circle 类继承。
6.方 法 重 写:
子类从父类中继承方法。有时,子类需要修改父类中定义的方法的实现,这称作方法重
写(method overriding)。
注意:
1.
仅当实例方法是可访问时,它才能被覆盖。因为私有方法在它的类本身以外是不能
访问的,所以它不能被覆盖。如果子类中定义的方法在父类中是私有的,那么这两
个方法完全没有关系。
2.
与实例方法一样,静态方法也能被继承。但是,静态方法不能被覆盖。如果父类中
定义的静态方法在子类中被重新定义,那么在父类中定义的静态方法将被隐藏。可
以使用语法:父类名 .静态方法名( SuperClassName.staticMethodName) 调用隐藏的
静态方法。
7.方法重写与重载:
注意:
1.
方法重写发生在通过继承而相关的不同类中;方法重载可以发生在同一个类中,也
可以发生在由于继承而相关的不同类中。
2.
方法重写具有同样的签名和返回值类型;方法重载具有同样的名字,但是不同的参
数列表。
为了避免错误,可以使用一个特殊的 Java 语法,称 为 重 写 标 注( override annotation),在子类的方法前面放一个 @Override。
例如:
public class CircleFromSimpleGeometricObject
extends SimpleCeometricObject {
// Other methods are omitted
@Override
public String toStringO {
return super.toStringO + "\nradius is •• + radius;
}
}
该标注表示被标注的方法必须重写父类的一个方法。如果具有该标注的方法没有重写父
类的方法,编译器将报告一个错误。例如,如果 toString 被错误地输人为 tostring, 将报
告一个编译错误。如果没有使用重写标注,编译器不会报告错误。使用标注可以避免错误。
8.Object 类及其 toString()方法:
如果在定义一个类时没有指定继承性,那么这个类的父类就被默认为是 Object。
诸如 String、StringBuilder、Loan 和 GeometricObject 这样的类都是 Object的隐含子类(此前在本书中见到的所有主类也是如此)。熟悉 Object 类提供的方法是非常重要的,因为这样就可以在自己的类中使用它们。
toStringO 方法的签名是:
public String toStringO
调用一个对象的 toStringO 会返回一个描述该对象的字符串。默认情况下,它返回一
个由该对象所属的类名、at 符号(@) 以及该对象十六进制形式的内存地址组成的字符串。
9.多态:
面向对象程序设计的三大支柱是封装、继承和多态。
首先,定义两个有用的术语:子类型和父类型。一个类实际上定义了一种类型。子类定义的类型称为子类型(subtype), 而父类定义的类型称为父类型(supertype)。因此,可以说Circle 是 GeometricObject的子类型,而 GeometricObject 是 Circle 的父类型。
继承关系使一个子类继承父类的特征,并且附加一些新特征。子类是它的父类的特殊化,每个子类的实例都是其父类的实例,但是反过来就不成立。
10.对象转换和 instanceof 运算符:
11.Object 类的 equals 方法:
在 Object 类中定义的另外一个经常使用的方法是 equals 方法。
它的签名是:
public boolean equals(Object o)
这个方法测试两个对象是否相等。调用它的语法是:
objectl.equals(object 2);
Object 类中 equals 方法的默认实现是:
public boolean equals(Object obj) {
return (this == obj);
}
这个实现使用 == 运算符检测两个引用变量是否指向同一个对象。因此,应该在自己的客户类中重写这个方法,以测试两个不同的对象是否具有相同的内容。
12.ArrayList 类:
现在,我们介绍一个很有用的用于存储对象的类了。可以创建一个数组存储对象但是这个数组一旦创建,它的大小就固定了。Java 提供 ArrayList 类来存储不限定个数的对象。
13.防止扩展和重写:
有时候,可能希望防止类扩展。在这种情况下,使用 final 修饰符表明一个类是最终
的,是不能作为父类的。Math 类就是一个最终类。String、StringBuilder 和 StringBuffer类也可以是最终类。
例如,下面的类 A 就是最终类,是不能被继承的:
public final class A {
}
也可以定义一个方法为最终的,最终方法不能被它的子类重写。
例如,下面的方法是最终的,是不能重写的:
public class Test {
public final void m(){
}
}
14.关于继承应该注意的几个关键点:
1.
和传统的理解不同,子类并不是父类的一个子集。实际上,一个子类通常比它的父 类包含更多的信息和方法。
2.
父类中的私有数据域在该类之外是不可访问的。因此,不能在子类中直接使用。但 是,如果父类中定义了公共的访问器 / 修改器,那么可以通过这些公共的访问器 / 修
改器来访问和修改它们。
3.
不是所有的 “是一种”(is-a) 关系都该用继承来建模。例如:正方形是一种矩形,但
是不应该定义一个 Square 类来扩展 Rectangle 类,因为 width 和 height 属性并不适合于正方形。应该定义一个继承自 CeometricObject 类的 Square 类,并为正方形的边定义一个 side 属性。
4.
继承是用来为 “是一种” 关系( is-a) 建模的。不要仅仅为了重用方法这个原因而盲
目地扩展一个类。例如:尽管 Person 类和 Tree 类可以共享类似高度和重量这样的通用特性,但是从 Person 类扩展出 Tree 类是毫无意义的。一个父类和它的子类之间必须存在 “是一种”(is-a) 关系。
5.
某些程序设计语言是允许从几个类派生出一个子类的。这种能力称为多重(multiple inheritance)。但是在 Java 中是不允许多重继承的。一个 Java 类只可能直接继承自一个父类。这种限制称为单一继承( single inheritance)。如果使用 extends 关键字来定义一个子类,它只允许有一个父类。然而,多重继承是可以通过接口来实现的。
来源:https://blog.csdn.net/weixin_45333967/article/details/98967042