多态
多态:可以理解为事物的多种体现形态—人: 男人,女人 / 动物: 狗,猫,猪
多态体现:
父类的引用指向自己的子类对象 / 父类的引用也可以接受自己的子类对象… Animal animal=newDog();----父类引用指向Dog子类的具体实现)
多态的前提: 类与类之间必须有联系:要么继承,要么实现…通常存在覆盖
多态好处: 提高程序的拓展性
多态弊端: 只能使用父类的引用访问父类的成员
代码演示 1 -----
/*
动物 / 猫/ 狗
*/
abstract class Animal {
abstract public void eat();
}
class Dog extends Animal {
public void eat() {
System.out.println("啃骨头");
}
public void seeHome() {
System.out.println("看家");
}
}
class Cat extends Animal {
public void eat() {
System.out.println("吃鱼");
}
public void catchMice() {
System.out.println("抓老鼠");
}
}
class AnimalDemo {
public static void main(String[] args) {
Animal c1 = new Cat(); //类型提升,向上转型,父类引用指向子类对象
c1.eat(); //只能调用父类中的方法
Cat c2 = (Cat) c1; //向下转型,强制将父类引用转换成子类类型
c2.catchMice(); //现在就可以调用该子类特有方法
funtion(new Dog());
}
/*dog.eat() cat.eat()
由于子类都调用的方法 eat() ,可以将调用封装起来,简化代码....后续演示会继续优化成类
*/
public static void funtion(Animal animal) {//Animal animal=new Cat();多态体现
animal.eat();
if (animal instanceof Cat) { //如果匹配到Cat,就向下转型,使其可以调用自身特有方法
Cat cat = (Cat) animal;
cat.catchMice();
} else if (animal instanceof Dog) {
Dog dog = (Dog) animal;
dog.seeHome();
}
}
}
代码演示 2-----
/*
基础班学生: 学习,睡觉
高级版学生: 学习,睡觉
*/
abstract class Student {
abstract public void study();
public void sleep() {
System.out.println("躺着睡");
}
}
/*
由这个类调用父类引用指向子类的方法,由这个类完成调用动作
这样将对象调用这件事就变简单了
*/
class Dostudent {
public void dosome(Student student) {
student.study();
student.sleep();
}
}
class BaseStudent extends Student {
public void study() {
System.out.println("base study");
}
public void sleep() {
System.out.println("坐着睡"); //重写sleep
}
}
class AdvStudent extends Student {
public void study() {
System.out.println("adv study");
}
}
class StudentDemo {
public static void main(String[] args) {
Dostudent ds = new Dostudent();
ds.dosome(new BaseStudent()); //基础班学生做的事
ds.dosome(new AdvStudent()); //高级版学生做的事
}
}
在多态中成员函数的特点:
在编译时期:参阅引用的父类中是否有调用的方法,如果有,则编译通过,否则编译失败
在运行时期:参阅对象所属的类中是否有调用方法
简单总结就是:成员函数在多态调用时,编译看引用的父类的方法,运行看对象所属子类的方法
多态中成员变量的特点: 无论编译还是运行,都参阅引用的父类
–
多态中静态成员函数: 无论编译还是运行,都参阅引用的父类
代码演示 3 ----
class Fu{
int num=5;
public void method1(){
System.out.println("fu_method_1");
}
public void method2(){
System.out.println("fu_method_2");
}
public static void method4(){
System.out.println("fu_methid_4");
}
}
class Zi extends Fu{
int num=10;
public void method1(){
System.out.println("zi_method_1");
}
public void method3(){
System.out.println("zi_method_3");
}
public static void method4(){
System.out.println("zi_methid_4");
}
}
public class DEMO {
public static void main(String[] args) {
Fu f=new Zi(); //父类引用指向子类对象
f.method1();
f.method2();
f.method3(); //这个会编译失败,,因为是多态引用,父类中没有该方法
f.method4(); //多态中静态函数参阅的是引用的父类
System.out.println(f.num); //因为是多态中,所以参阅的是所引用的父类
}
}