15. 多态
15.1 多态概念
java中**多态(Polymorphism )**是指不同对象在调用相同名称方法时,表现的多种不同行为。例如,要实现一个动物叫的方法,由于每种动物的叫声不同,因此可以在方法中接收一个动物参数,当传入的是猫类时发出猫叫,传入狗类时发出狗的叫声。
java中多态允许父类的指针或引用指向子类的对象,并调用相应的方法。多态需要满足以下三个条件:
- 继承:子类继承父类,存在继承关系。
- 重写:子类对父类的方法进行实现或重写,从而可以展现子类的行为特征。
- 父类的指引指向子类的对象:可以将子类的对象赋给父类类型的引用。
15.1.1 继承普通类实现多态
public class Animal {void speak() {System.out.println("Animal speaks");}
}public class Dog extends Animal {@Overridevoid speak() {System.out.println("Dog barks");}
}public class Cat extends Animal {@Overridevoid speak() {System.out.println("Cat barks");}
}public class PolymorphismExample {public static void main(String[] args) {Animal myAnimal = new Dog(); // 父类引用指向子类对象myAnimal.speak(); // 输出 "Dog barks",多态表现Animal myAnimal1 = new Cat(); // 父类引用指向子类对象myAnimal1.speak(); // 输出 "Cat barks",多态表现}
}
15.1.2 继承抽象类实现多态
abstract class Animal {abstract void shout();
}// Cat继承Animal
class Cat extends Animal{// 实现父类的shout方法public void shout(){System.out.println("喵喵....");}
}// Dog继承Animal
class Dog extends Animal{// 实现父类的shout方法public void shout(){System.out.println("汪汪....");}
}public class PolymorphismExample{public static void main(String[] args) {Animal dog = new Dog(); // 父类引用指向子类对象dog.shout(); // 输出 "汪汪....",多态表现Animal cat = new Cat(); // 父类引用指向子类对象cat.shout(); // 输出 "喵喵....",多态表现}
}
15.1.3 使用接口实现多态
interface Shape {void draw();
}class Circle implements Shape {public void draw() {System.out.println("Drawing a circle");}
}
class Triangle implements Shape {public void draw() {System.out.println("Drawing a triangle");}
}public class PolymorphismExample{public static void main(String[] args) {Shape circel = new Circle();circel.draw(); // Output: "Drawing a circle"Shape triangle = new Triangle();triangle.draw(); // Output: "Drawing a triangle"}
}
15.1.4 父类形参接收子类实参
interface Shape {void draw();
}class Circle implements Shape {public void draw() {System.out.println("Drawing a circle");}
}
class Triangle implements Shape {public void draw() {System.out.println("Drawing a triangle");}
}class ShapeService(){// Shape shape是父类类型public void drawShape(Shape shape){shape.draw();}
}public class PolymorphismExample{public static void main(String[] args) {ShapeService shapeService = new ShapeService();Circle circel = new Circle();// 传递子类实参shapeService.drawShape(circel); // Output: "Drawing a circle"Triangle triangle = new Triangle();// 传递子类实参shapeService.drawShape(triangle); // Output: "Drawing a triangle"}
}
- 练习1
- 定义墨盒接口InkBox,定义方法String getColor()用于获得墨盒颜色。
- 定义纸张接口Paper, 定义方法String getSize()用于获得纸张大小。
- 定义黑白墨盒类GrayInkBox实现InkBox接口,实现getColor方法,返回"黑白"。
- 定义彩色墨盒类ColorInkBox实现InkBox接口,实现getColor方法,返回"彩色"。
- 定义A4纸类A4Paper实现Paper接口,实现方法getSize,返回”A4“。
- 定义B5纸类B5Paper实现Paper接口,实现方法getSize,返回”B5“。
- 定义MyPrinter类,定义属性InkBox box,Paper paper,String brand,封装后定义方法work, 输出何种品牌打印机使用何种颜色墨盒在何种尺寸纸张上打印文字。
package task;
public interface InkBox {// 获得墨盒颜色String getColor();
}package task;
public interface Paper {// 获得纸张尺寸String getSize();
}package task;
public class A4Paper implements Paper {@Overridepublic String getSize() {return "A4";}
}package task;
public class B5Paper implements Paper {@Overridepublic String getSize() {return "B5";}
}package task;
public class ColorInkBox implements InkBox {@Overridepublic String getColor() {return "彩色";}
}package task;
public class GrayInkBox implements InkBox {@Overridepublic String getColor() {return "黑色";}
}package task;
public class MyPrinter {private InkBox box;private Paper paper;private String brand;public String getBrand() {return brand;}public void setBrand(String brand) {this.brand = brand;}public Paper getPaper() {return paper;}public void setPaper(Paper paper) {this.paper = paper;}public InkBox getBox() {return box;}public void setBox(InkBox box) {this.box = box;}public void work() {System.out.println(getBrand() + "打印机使用" + box.getColor() + "墨盒在" + paper.getSize() + "纸张上打印文字");}
}package task;
public class MyPrinterTest {public static void main(String[] args) {MyPrinter myPrinter = new MyPrinter();// 彩色墨盒对象ColorInkBox colorInkBox = new ColorInkBox();myPrinter.setBox(colorInkBox);// 纸张对象A4Paper a4Paper = new A4Paper();myPrinter.setPaper(a4Paper);// 设置品牌myPrinter.setBrand("佳能");// 调用工作方法myPrinter.work(); // 佳能打印机使用彩色墨盒在A4纸张上打印文字// 另外一台打印机MyPrinter myPrinter1 = new MyPrinter();myPrinter1.setBrand("惠普");myPrinter1.setBox(new GrayInkBox());myPrinter1.setPaper(new B5Paper());myPrinter1.work(); // 惠普打印机使用黑色墨盒在B5纸张上打印文字}
}
15.2 对象类型转换
对象类型转换注意分为以下两种情况:
1. 向上转型: 子类对象 转换为 父类类型。
2. 向下转型: 父类对象 转换为 子类类型。
向上转型会自动完成,向下转型要强制转换。
15.2.1 向上转型
class Animal {public void shout() {System.out.println("Animal shout....");}
}