概念
- 指的是类实例的相同方法在不同情形下有不同的表现形式
- 多态机制使得具有不同内部结构的对象可以共享相同的外部接口(利用多态可以得到良好的设计)
覆写(重写)
定义
子类定义了与父类方法名称、参数列表、返回值完全相同的方法 。被覆写的方法不能拥有比父类更为严格的访问控制权限
重写规则
- 参数列表必须完全与被重写方法的相同;
- 返回类型必须完全与被重写方法的返回类型相同;
- 访问权限不能比父类中被重写的方法的访问权限更低。(private<default(即啥也不写,包访问权限)<public)。
- 父类的成员方法只能被它的子类重写。
- 声明为final的方法不能被重写。
- 声明为static的方法不能被重写,但是能够被再次声明。
- 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为private和final的方法。
- 重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。
- 构造方法不能被重写。
- 如果不能继承一个方法,则不能重写这个方法。
重写与重载的区别
区别点 | 重载方法 | 重写方法 |
---|---|---|
参数列表 | 可以不同 | 相同 |
返回类型 | 可以不同 | 相同 |
异常 | 可以不同 | 可以减少或删除,一定不能抛出新的或者更广的异常 |
访问 | 可以不同 | 一定不能做更严格的限制(可以降低限制) |
总结
方法的重写(Overriding)和重载(Overloading)是java多态性的不同表现,重写是父类与子类之间多态性的一种表现,重载可以理解成多态的具体表现形式。
- 方法重载是一个类中定义了多个方法名相同,而他们的参数的数量不同或数量相同而类型和次序不同,则称为方法的重载(Overloading)。
- 方法重写是在子类存在方法与父类的方法的名字相同,而且参数的个数与类型一样,返回值也一样的方法,就称为重写(Overriding)。
- 方法重载是一个类的多态性表现,而方法重写是子类与父类的一种多态性表现。
多态的优点
- 消除类型之间的耦合关系
- 可替换性
- 可扩充性
- 接口性
- 灵活性
- 简化性
多态存在的三个必要条件
- 继承
- 重写
- 父类引用指向子类对象
class Person{
public void print(){
System.out.println("我是父类!");
}
}
class Student extends Person{
public void print(){
System.out.println("我是子类!");
}
}
public class Test{
public static void main(String[] args) {
Person per = new Student();
per.print();
}
}
向上转型与向下转型
向上转型:用于参数统一化
用法: 父类 父类引用 = new 子类()
向下转型:当父类引用需要调用子类扩充方法时,才需要向下转型
用法: 子类 子类引用= (强转)父类引用
要发生向下转型,必须先发生向上转型( 认爹)
public class Test {
public static void main(String[] args) {
show(new Cat()); // 以 Cat 对象调用 show 方法
show(new Dog()); // 以 Dog 对象调用 show 方法
Animal a = new Cat(); // 向上转型
a.eat(); // 调用的是 Cat 的 eat
Cat c = (Cat)a; // 向下转型
c.work(); // 调用的是 Cat 的 work
}
public static void show(Animal a) {//向上转型
a.eat();
// 类型判断
if (a instanceof Cat) { // 猫做的事情
Cat c = (Cat)a; //向下转型
c.work();
} else if (a instanceof Dog) { // 狗做的事情
Dog c = (Dog)a; //向下转型
c.work();
}
}
}
abstract class Animal {
abstract void eat();
}
class Cat extends Animal {
public void eat() {
System.out.println("吃鱼");
}
public void work() {
System.out.println("抓老鼠");
}
}
class Dog extends Animal {
public void eat() {
System.out.println("吃骨头");
}
public void work() {
System.out.println("看家");
}
}
-
运行时异常:ClassCastException(类型转换异常)
-
引用名 instanceof 类,表示该引用是否能表示该类实例
多态性总结:
- 对象多态性的核心在于方法的覆写。
- 通过对象的向上转型可以实现接收参数的统一,向下转型可以实现子类扩充方法的调用(一般不操作向下 转型,有安全隐患)。
- 两个没有关系的类对象是不能够进行转型的,一定会产生 ClassCastException。