15. 多态
15.1 多态概念
java中**多态(Polymorphism )**是指不同对象在调用相同名称方法时,表现的多种不同行为。例如,要实现一个动物叫的方法,由于每种动物的叫声不同,因此可以在方法中接收一个动物参数,当传入的是猫类时发出猫叫,传入狗类时发出狗的叫声。
java中多态允许父类的指针或引用指向子类的对象,并调用相应的方法。多态需要满足以下三个条件:
- 继承:子类继承父类,存在继承关系。
- 重写:子类对父类的方法进行实现或重写,从而可以展现子类的行为特征。
- 父类的指引指向子类的对象:可以将子类的对象赋给父类类型的引用。
15.1.1 继承普通类实现多态
public class Animal {
void speak() {
System.out.println("Animal speaks");
}
}
public class Dog extends Animal {
@Override
void speak() {
System.out.println("Dog barks");
}
}
public class Cat extends Animal {
@Override
void 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 {
@Override
public String getSize() {
return "A4";
}
}
package task;
public class B5Paper implements Paper {
@Override
public String getSize() {
return "B5";
}
}
package task;
public class ColorInkBox implements InkBox {
@Override
public String getColor() {
return "彩色";
}
}
package task;
public class GrayInkBox implements InkBox {
@Override
public 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....");
}
}