多态
概述:某一个事物,在不同时空表现出来的不同形态
例:水、冰、水蒸气
举例:
猫 m = new 猫();
给以猫声明的引用变量m赋值一个猫()的实例,那么猫的实例表现的特征就是猫
动物 d = new 猫();
给以动物声明的引用变量d赋值一个猫()的实例,那么猫的实例表现的特征就是动物
补充概念:****域:field,域是一种属性,可以是一个类变量,一个对象变量,一个对象方法变量或者是一个函数的参数。
多态的分类:
编译时多态:(方法重载)可以发生在任何类中
运行时多态:1.要有继承关系 2.要有方法覆盖 3.要有父类引用指向子类对象
方法覆盖:
定义:方法覆盖是指在子类中替换父类或祖先类对某个方法的实现
通过子类重新定义与父类或祖先类中具有同样 方法签名 和 返回类型 的方法来实现
覆盖的方法可以与父类的方法保持相同的可访问范围,也可以修改访问控制修饰符增大可访问范围,但是不能减小可访问范围
private -> default -> protected ->public
方法覆盖的几种特殊情况:
1.被final修饰的方法不允许在子类中覆盖
2.父类被覆盖的方法参数列表中被声明为final的参数在子类的覆盖方法中可以不必指定为final
3.子类可以访问到的 父类或祖先类的方法才能被覆盖(如父类中private修饰的方法)
4.静态方法不能被覆盖(静态方法也不存在运行时多态)
父类成员变量的隐藏:
1.父类类体访问到的是父类的同名域
2.子类类体访问到的是子类的同名域
父类方法的覆盖:
1.如果是通过子类对象访问父类方法,那么在父类类体中,访问到的是子类中的覆盖方法
2.在子类类体中,访问到的是子类的覆盖方法
3.但是,在子类类体中,仍然可以通过super关键字,访问到父类被覆盖的方法
多态中成员访问的特点
成员变量:
编译看左边(引用变量的声明变量)
运行看左边(实际访问的成员变量,也是由引用变量的声明变量确定的)
方法:
编译看左边(引用变量的声明变量)
运行看右边(实际访问的方法由引用变量所指向的对象的实际类型决定)
public class PolyDemo01 {
public static void main(String[] args) {
//发生方法覆盖的第三个条件
//java是一种强类型的语言
// A a = A 类型的实例
// A a = A 类型 以及A类型子类的实例
Animal animal = new Cat();
//animal = new Animal();
//1. 利用父类引用访问父类中的同名域
System.out.println(animal.weight);
//2. 运行时多态 (在运行时,访问的方法,取决于引用变量所指向的对象的实际类型,也就是看右边)
//输出的是Cat类的shout()
animal.shout(0);
//编译器,在判定通过某一个引用变量,能不能访问某个成员,是由引用变量的声明类型来决定的(也就是看左边)
//animal.height;//编译错误
((Cat) animal).height;
//animal.go();//编译错误
((Cat) animal).go;
}
}
class Animal {
int weight = 1;
public Animal() {
System.out.println("Animal weight = " + weight);
}
void shout(final int i) {
System.out.println("Animal shout");
}
}
class Cat extends Animal {
int weight = 100;
int height = 180;
public Cat() {
System.out.println("Cat weight = " + weight);
}
@Override
public void shout(int i) {
System.out.println("cat shout");
//如通要访问父类中被子类覆盖的方法,只能在子类类体中,通过super关键字来访问
//super.shout(0);
}
public void go() {
}
}
网友评论