笔记

mac2026-10-05  0

1. 多态的概述

1.1 多态的概述

同一种事物表现出来的多种形态则称为多态。

"俊杰" ==> 班长

"俊杰" ==> 儿子

"俊杰" ==> 父亲

"俊杰" ==> 路人甲

1.2 多态的前提

必须有子父类关系或类实现接口关系必须有方法重写必须有父类引用指向子类对象或接口引用指向实现类对象

1.3 多态的格式

父类类名 变量名 = new 子类类名();接口名 变量名 = new 接口实现类();

2. 多态案例

    // 抽象类:动物父类 abstract class Animal{ public abstract void eat(); public abstract void sleep(); } // 子类Dog 继承 动物类 class Dog extends Animal{ ​ @Override public void eat() { System.out.println("狗吃骨头"); } @Override public void sleep() { System.out.println("狗趴着睡"); } } ​ interface Play{ public void playing(); } ​ class Cat implements Play{ @Override public void playing() { System.out.println("和猫玩耍"); } } ​ // 人类 class Person{ public void eat() { System.out.println("人吃饭"); } } // 学生类 class Student extends Person{ public void eat() { System.out.println("学生吃饭"); } } ​ public class Demo01 { public static void main(String[] args) { // 创建Dog对象 Dog d = new Dog(); // 调用方法 d.eat(); d.sleep(); System.out.println("--------"); // 使用多态形式 Animal a = new Dog(); a.eat(); a.sleep();   // 使用多态形式:创建猫对象 Play p = new Cat(); p.playing();   // 使用多态形式:创建学生对象 Person stu = new Student(); stu.eat(); } }

3. 多态的注意细节

多态的注意事项

多态情况下,如果子父类出现同名的成员变量时,访问的是父类的成员变量。多态情况下,如果子父类出现同名的成员方法时,访问的是子类重写后的成员方法     编译特性 成员变量:编译看左边,运行看左边。 成员方法:编译看左边,运行看右边。 成员变量:属于静态绑定 成员方法:属于动态绑定

4. 多态的好处(优点)与弊端(缺点)

多态的缺点

不能访问子类特有的成员:成员变量和成员方法

多态的优点

提高了代码的复用性。提高了代码的扩展性。提高了代码的维护性。

5. 多态的使用场景

作为方法的形式参数,可以接收更多数据类型的对象。 作为方法的返回值类型,可以方法更多的数据类型的对象

6. 多态的转型

向上转型:父类引用指向子类对象的过程就是向上转型的结果。   Animal a = new Dog(); 向下转型:将父类引用强制转换为子类引用的过程     格式:子类类型 变量名 = (子类类型)父类引用;

7. instanceof关键字

作用:用来判断多态后父类引用到底指向哪个子类类型的对象。格式:boolean b = 引用变量 instanceof 类名或接口名;注意事项:如果instanceof关键字后面的是类名,则要求引用变量和类之间有子父类关系。     /** * 抽象类 动物类 */ public abstract class Animal { // 成员方法 public abstract void eat(); public abstract void sleep(); } public class Dog extends Animal implements Play { @Override public void eat() { System.out.println("狗吃肉"); } ​ @Override public void sleep() { System.out.println("趴着睡"); }   public void lookHome() { System.out.println("老老实实看家"); } ​ @Override public void playing() { System.out.println("狗玩耍的方法"); } } ​ public class Cat extends Animal { @Override public void eat() { System.out.println("猫吃鱼"); } @Override public void sleep() { System.out.println("猫躺着睡"); } public void catchMouse() { System.out.println("猫捉老鼠"); } } ​ public interface Play { void playing(); } ​ /* * 测试类 */ public class Demo01 { public static void main(String[] args) { // 养一只狗对象 Dog d1 = new Dog(); // 喂养狗 /*d1.eat(); d1.sleep();*/ // feedDog(d1); feedAnimal(d1);   // 再养一只狗 Dog d2 = new Dog(); /*d2.eat(); d2.sleep();*/ // feedDog(d2); feedAnimal(d2); // 再养一只狗 Dog d3 = new Dog(); /*d3.eat(); d3.sleep();*/ // feedDog(d3); feedAnimal(d3);   // 养一只猫 Cat c1 = new Cat(); /*c1.eat(); c1.sleep();*/ // feedCat(c1); feedAnimal(c1);   // 再养一只猫 Cat c2 = new Cat(); /*c2.eat(); c2.sleep();*/ // feedCat(c2); feedAnimal(c2);   feedAnimal(new Tiger());   // 调用工厂方法获得一只动物 Animal aa =  productAnimal(1); // Animal aa = new Dog() aa.eat(); aa.sleep(); } /** * 工厂方法 * type = 1 狗 * type = 2 猫 */ public static Animal productAnimal(int type) { if(type == 1) { //此次省略一万行代码 return new Dog(); } else if (type == 2) { return new Cat(); } return new Tiger(); } /** * 喂养动物 */ public static void feedAnimal(Animal a) { // Animal a = new Tiger(); a.sleep(); a.eat();   // 格式:boolean b = 引用变量 instanceof 数据类型; boolean b = a instanceof Dog; if(a instanceof Dog) { // 格式:子类类型 变量名 = (子类类型)父类引用; Dog d = (Dog)a; // 调用子类特有的成员 // d.lookHome(); } else if(a instanceof Cat) { // 向下转型为Cat Cat c = (Cat)a; c.catchMouse(); } // 判断引用变量a是否实现了指定的接口:Play,如果实现了则返回true,否则false if(a instanceof Play) { // 调用狗的playing方法 Play p = (Play)a; p.playing(); } } /* *//** * 喂养猫 * @param d *//* public static void feedCat(Cat c) { c.eat(); c.sleep(); } *//** * 喂养狗 * @param d *//* public static void feedDog(Dog d) { d.eat(); d.sleep(); }*/ }
最新回复(0)