版权声明:博主GitHub网址https://github.com/29DCH,欢迎大家前来交流探讨和fork。 https://blog.csdn.net/CowBoySoBusy/article/details/82084319
简单的说就是父类引用指向子类对象.一种方法, 多种实现.
规则:
成员变量:编译看左边(父类),运行看左边(父类);
成员方法:编译看左边(父类),运行看右边(子类,动态绑定).
public class Polymorphic {
public static void main(String[] args) {
/*Father f = new Son(); //父类引用指向子类对象
System.out.println(f.num);
Son s = new Son();
System.out.println(s.num);*/
Father f = new Son();
//f.print();
f.method(); //相当于是Father.method()
}
}
/*
成员变量
编译看左边(父类),运行看左边(父类)
成员方法
编译看左边(父类),运行看右边(子类)。动态绑定
静态方法
编译看左边(父类),运行看左边(父类)。
(静态和类相关,算不上重写,所以,访问还是左边的)
只有非静态的成员方法,编译看左边,运行看右边
*/
class Father {
int num = 10;
public void print() {
System.out.println("father");
}
public static void method() {
System.out.println("father static method");
}
}
class Son extends Father {
int num = 20;
public void print() {
System.out.println("son");
}
public static void method() {
System.out.println("son static method");
}
}
输出:
father static method
多态中的成员变量:
多态中的成员方法:
基本数据类型和引用数据类型的自动类型提升和强制类型转换:
向上自动转型就不说了,主要看一下向下的强制转换。
多态的好处:
提高了代码的维护性(继承保证)
提高了代码的扩展性(由多态保证)
可以当作形式参数,可以接收任意子类对象
public class Test {
public static void main(String[] args) {
Person p = new SuperMan(); //父类引用指向子类对象,超人提升为了人
//父类引用指向子类对象就是向上转型
System.out.println(p.name);
p.say();
SuperMan sm = (SuperMan)p; //向下转型
sm.fly();
/*
基本数据类型自动类型提升和强制类型转换
*/
int i = 10;
byte b = 20;
//i = b; //自动类型提升
//b = (byte)i; //强制类型转换
}
}
class Person {
String name = "abc";
public void say() {
System.out.println("说话");
}
}
class SuperMan extends Person {
String name = "SuperMan";
public void say() {
System.out.println("超人说话");
}
public void fly() {
System.out.println("到处飞救人");
}
}
输出:
abc 超人说话 到处飞救人
多态的弊端:
不能使用子类的特有属性和行为。需要向下强制类型转换才行。
多态接收任意子类对象:
public class Test {
public static void main(String[] args) {
//Cat c1 = new Cat();
//c1.eat();
method(new Cat());
method(new Dog());
//Animal a = new Cat(); //开发的时候是很少在创建对象的时候用父类引用指向子类对象,直接创建子类对象更方便,可以使用子类中的特有属性和行为
}
//Cat c = new Dog();狗是一只猫,这是错误的
/*public static void method(Cat c) {
c.eat();
}
public static void method(Dog d) {
d.eat();
}*/
//如果把狗强转成猫就会出现类型转换异常,ClassCastException
public static void method(Animal a) { //当作参数的时候用多态最好,因为扩展性强
//关键字 instanceof 判断前边的引用(对象)是否是后边的数据类型
if (a instanceof Cat) {
Cat c = (Cat)a;
c.eat();
c.catchMouse();
}else if (a instanceof Dog) {
Dog d = (Dog)a;
d.eat();
d.lookHome();
}else {
a.eat();
}
}
}
/*
* A:多态的好处
* a:提高了代码的维护性(继承保证)
* b:提高了代码的扩展性(由多态保证)
* B:案例演示
* 多态的好处
* 可以当作形式参数,可以接收任意子类对象
* C:多态的弊端
* 不能使用子类的特有属性和行为。
*/
class Animal {
public void eat() {
System.out.println("动物吃饭");
}
}
class Cat extends Animal {
public void eat() {
System.out.println("猫吃鱼");
}
public void catchMouse() {
System.out.println("猫抓老鼠");
}
}
class Dog extends Animal {
public void eat() {
System.out.println("狗吃骨头");
}
public void lookHome() {
System.out.println("狗看家");
}
}
输出:
猫吃鱼 猫抓老鼠 狗吃骨头 狗看家