3 Inheritance and Polymorphism¶
说明
本文档正在更新中……
说明
本文档仅涉及部分内容,仅可用于复习重点知识
1 Inheritance¶
语法:
在 Java 中,如果一个类没有显式地 extends
任何其他类,它会默认继承 java.lang.Object
类
因此,Object
类是 Java 所有类的最终父类,所有对象都拥有 Object
类的方法,如 toString()
、equals()
、hashCode()
等
构造方法与继承:
- 构造方法不会被继承
- 子类的构造过程总是会先调用父类的构造方法,以确保父类部分被正确初始化
1.1 super
¶
super
关键字用于引用直接父类的成员
-
调用父类构造方法:
super()
- 必须是子类构造方法中的第一条语句
- 如果子类构造方法中没有显式调用
super()
,Java 会自动调用父类的无参构造方法。如果父类没有无参构造方法,则必须在子类中显式调用super()
并传入相应参数
-
访问父类成员:
super.methodName()
或super.fieldName
- 当子类重写了父类的方法或定义了同名字段时,可以用
super
来明确调用父类的版本
- 当子类重写了父类的方法或定义了同名字段时,可以用
1.2 Name Hiding¶
1.字段隐藏
当子类定义了与父类同名的字段时,会发生字段隐藏:
2.静态方法隐藏
当子类定义了与父类同名的静态方法时,会发生静态方法隐藏:
与 C++ 的区别
在 C++ 中:
但在 Java 中:
- Java:使用基于方法签名的重载解析,子类不会隐藏父类中签名不同的方法
- C++:一旦子类定义了同名方法,就会隐藏所有父类的同名方法(无论参数是否相同)
1.3 Method Overriding¶
子类可以提供一个与父类方法具有相同方法签名(方法名、参数列表)和返回类型(或其子类型)的新实现
@Override
注解:一个推荐使用的注解,用于告诉编译器该方法意图重写父类方法。如果拼写错误或参数不匹配,编译器会报错
规则:
- 访问修饰符的限制不能更严格(例如,父类是
public
,子类不能是protected
) - 不能重写 final 或 static 方法
1.4 Upcast¶
与 C++ 类似
1.4.1 instanceof
¶
一个操作符。返回一个 boolean
值,表示对象是否是指定类型或其子类型的实例
1.5 继承类型¶
- 单继承
- 多层继承:一个类可以继承一个已经是子类的类,形成继承链
- 层级继承:一个父类可以被多个子类继承
无多重继承,这是为了避免“菱形问题”带来的复杂性和歧义。Java 通过 Interface 来变相实现多重继承的好处。一个类可以实现多个接口
1.6 abstract
¶
1.6.1 抽象方法¶
抽象方法是一个只有方法声明、没有方法体(即没有 {}
代码块)的方法。它必须在抽象类中声明
其目的在于强制子类提供该方法的具体实现。它定义了一个“契约”,任何继承这个抽象类的非抽象子类都必须遵守这个契约
特点:
- 没有方法体,以分号
;
结尾 - 必须存在于一个抽象类中
- 不能是
private
的,因为private
方法不能被子类重写 - 不能是
final
的,因为final
方法不能被重写 - 不能是
static
的,因为static
方法属于类,而抽象方法需要被子类的实例重写
1.6.2 抽象类¶
作为其他类的父类,提供一个通用的模板。它用于被继承,而不是用于被实例化
特点:
- 不能被实例化:不能使用
new
关键字创建抽象类的对象 - 可以包含抽象方法和非抽象方法:抽象类可以同时拥有带方法体的具体方法和不带方法体的抽象方法。这使得抽象类能提供一些通用实现,同时又保留一些部分让子类去定义
- 可以有构造方法:抽象类的构造方法不能用来创建实例,但它会在子类实例化时被调用(通过
super()
),用于初始化父类的成员变量 - 可以有成员变量、静态方法等:抽象类和普通类一样,可以拥有各种成员
-
子类的责任:如果一个类继承了抽象类,它必须:
- 实现(重写)父类中所有的抽象方法
- 或者,如果它没有实现所有抽象方法,那么这个子类也必须被声明为
abstract