1. 多态概述
多态是面向对象思想中的一个非常重要的概念,在Java中,多态是指不同类的对象在调用同一个方法时表现出的多种不同行为。
例如,要实现一个动物叫声的方法,由于每种动物的叫声是不同的,因此可以在方法中接收一个动物类型的参数,当传入猫类对象时就发出猫类的叫声,传入犬类对象时就发出犬类的叫声。在同一个方法中,这种由于参数类型不同而导致执行效果不同的现象就是多态。
2. 多态类型
Java中多态主要有以下两种形式:
- 静态的多态,通过方法的重载实现。
- 动态的多态,又称对象的多态,通过方法的重写实现。
2.1 动态多态的前提
-
继承,在多态中必须存在有继承关系的子类和父类。
-
重写,子类对父类的方法进行重写。
-
父类引用指向子类对象。
2.2 多态的好处与弊端
- 好处,提高了程序的扩展性,定义方法使用父类型作为参数,在使用时用具体的子类型参与操作。
- 弊端,不能使用子类的特有功能。
2.3 多态形式
具体类多态、抽象类多态和接口多态。
3. 多态案例
-
案例需求
定义动物类抽象类Animal,定义其抽象方法shout(),方法用public修饰。
定义一个小猫类Cat,继承Animal类,在Cat类中覆盖Animal类中的方法shout(),输出“小猫喵喵叫”。
定义一个小狗类Dog,继承Animal类,在Dog类中覆盖Animal类中的方法shout(),输出“小狗汪汪叫”。
编写测试类,编写测试方法makeSound(Animal animal),测试动物叫声。
-
Animal类
public abstract class Animal {
public abstract void shout();
}
-
Cat类
public class Cat extends Animal{
@Override
public void shout() {
System.out.println("小猫喵喵叫");
}
}
-
Dog类
public class Dog extends Animal{
@Override
public void shout() {
System.out.println("小狗汪汪叫");
}
}
-
测试类
public class TestDemo {
@Test
public void testSound(){
//父类引用指向子类对象 测试小狗叫声
Animal animal = new Dog();
animal.shout();
//父类引用指向子类对象 测试小猫叫声
Animal animal2 = new Cat();
animal2.shout();
}
/**
* 测试动物叫声
* @param animal
*/
public void makeSound(Animal animal){
animal.shout();
}
}
4. 练习
- 案例需求
定义抽象类Shape,定义其抽象方法getArea(),方法用public修饰。
定义一个圆类Circle,继承Shape类,在Circle类中覆盖Shape类中的抽象方法getArea(),计算圆的面积。
定义一个正方形类Square,继承Shape类,在Square类中覆盖Shape类中的抽象方法getArea(),计算正方形的面积。
编写测试类,基于抽象类的多态,将每个图形的面积放到数组中,计算数组中所有图形的面积和。
-
Shape抽象类
public abstract class Shape {
public abstract double getArea();
}
-
Circle类
public class Circle extends Shape{
private double r;
public Circle(double r){
this.r = r;
}
@Override
public double getArea() {
return Math.PI * r * r;
}
}
-
Square类
public class Square extends Shape{
private double r;
public Square(double r){
this.r = r;
}
@Override
public double getArea() {
return r * r;
}
}
-
测试类
public class TestArea {
/**
* 求所有图形的面积和
*/
@Test
public void test(){
Shape[] shapes = new Shape[2];
shapes[0] = new Circle(1);
shapes[1] = new Square(2);
double sum = 0;
for(Shape shape : shapes){
sum += shape.getArea();
}
System.out.println("所有图形的面积和为:" + sum);
}
}
5. instanceof关键字
Java中可以使用instanceof关键字判断一个对象是否是某个类(或接口)的实例,语法格式如下所示。
对象 instanceof 类(或接口)
上述语法格式中,如果“对象”是指定的类的实例对象,则返回true,否则返回false。
public class Animal {
}
public class Cat extends Animal {
}
public class Dog extends Animal {
}
public class TestDemo {
@Test
public void test(){
Animal animal = new Animal();
Dog dog = new Dog();
Cat cat = new Cat();
if (animal instanceof Animal) {
System.out.println("animal 是 Animal 类型");
} else {
System.out.println("animal 不是 Animal 类型");
}
if (dog instanceof Animal) {
System.out.println("dog 是 Animal 类型");
} else {
System.out.println("dog 不是 Animal 类型");
}
if (cat instanceof Animal) {
System.out.println("cat 是 Animal 类型");
} else {
System.out.println("cat 不是 Animal 类型");
}
}
}