编程自学指南:java程序设计开发,类的多态详解课件
一、课程基本信息
学习目标
- 深入理解类的多态概念、作用及实现条件。
- 掌握多态在方法调用和参数传递中的应用。
- 能够运用多态进行实际的程序设计,提高代码的可扩展性和可维护性。
课程重点
- 多态的实现方式(继承、接口)。
- 方法重写与多态的关系。
- 多态在实际编程中的应用。
课程难点
- 理解多态的运行时绑定机制。
- 合理运用多态解决复杂的编程问题。
二、课程导入
生活中的多态实例
在生活中,多态现象十分常见。比如 “吃饭” 这个行为,不同的人吃饭的方式、习惯和食物选择可能不同。小孩可能用勺子吃饭,大人可能用筷子吃饭;南方人可能喜欢吃米饭,北方人可能喜欢吃面食。同样是 “吃饭” 这个行为,却有多种不同的表现形式,这就是生活中的多态。
编程中的需求引出
在 Java 编程里,假设我们要开发一个简单的宠物管理系统。系统中有不同种类的宠物,如猫、狗等,每种宠物都有 “叫” 的行为,但叫声不同。如果不使用多态,我们可能会为每种宠物编写单独的方法来处理它们的 “叫” 行为,代码会变得冗长且难以维护。而使用多态,我们可以统一处理不同宠物的 “叫” 行为,提高代码的复用性和可扩展性。
// 不使用多态的示例
class Cat {
void meow() {
System.out.println("喵喵喵");
}
}
class Dog {
void bark() {
System.out.println("汪汪汪");
}
}
public class NoPolymorphismExample {
public static void main(String[] args) {
Cat cat = new Cat();
Dog dog = new Dog();
cat.meow();
dog.bark();
}
}
三、多态的概念
定义
多态是面向对象编程的三大特性之一,它允许不同类的对象对同一消息做出不同的响应。简单来说,就是一个方法可以根据调用对象的不同而表现出不同的行为。
作用
- 提高代码的可扩展性:当需要添加新的子类时,不需要修改现有的调用代码,只需要在子类中实现相应的方法即可。
- 增强代码的可维护性:将不同对象的相同行为进行统一处理,减少了代码的重复,使代码结构更加清晰。
- 实现代码的灵活性:可以根据实际情况动态地选择调用不同子类的方法。
四、多态的实现条件
1. 继承或实现接口
多态通常基于继承或接口实现。子类继承父类,或者类实现接口,为多态提供了基础。
2. 方法重写
子类需要重写父类的方法,以实现不同的行为。方法重写要求方法名、参数列表和返回类型与父类方法相同,但方法体可以不同。
3. 父类引用指向子类对象
使用父类类型的引用变量来引用子类的对象,通过该引用调用重写的方法时,会根据实际对象的类型来决定执行哪个子类的方法。
示例代码
// 父类
class Animal {
void makeSound() {
System.out.println("动物发出声音");
}
}
// 子类
class Cat extends Animal {
@Override
void makeSound() {
System.out.println("喵喵喵");
}
}
class Dog extends Animal {
@Override
void makeSound() {
System.out.println("汪汪汪");
}
}
public class PolymorphismExample {
public static void main(String[] args) {
// 父类引用指向子类对象
Animal cat = new Cat();
Animal dog = new Dog();
cat.makeSound(); // 调用 Cat 类重写的方法
dog.makeSound(); // 调用 Dog 类重写的方法
}
}
五、多态在方法调用中的应用
动态绑定
在多态中,方法的调用是在运行时进行动态绑定的。即根据实际对象的类型来决定调用哪个子类的方法,而不是根据引用变量的类型。
示例代码
class Shape {
void draw() {
System.out.println("绘制形状");
}
}
class Circle extends Shape {
@Override
void draw() {
System.out.println("绘制圆形");
}
}
class Rectangle extends Shape {
@Override
void draw() {
System.out.println("绘制矩形");
}
}
public class PolymorphicMethodCall {
public static void main(String[] args) {
Shape[] shapes = new Shape[2];
shapes[0] = new Circle();
shapes[1] = new Rectangle();
for (Shape shape : shapes) {
shape.draw(); // 动态绑定,根据实际对象类型调用相应方法
}
}
}
六、多态在参数传递中的应用
以父类作为方法参数
在方法的参数列表中,可以使用父类类型作为参数,这样可以传递不同子类的对象,实现方法的通用性。
示例代码
class Fruit {
void taste() {
System.out.println("水果有味道");
}
}
class Apple extends Fruit {
@Override
void taste() {
System.out.println("苹果甜甜的");
}
}
class Orange extends Fruit {
@Override
void taste() {
System.out.println("橙子酸酸的");
}
}
class FruitTaster {
public static void tasteFruit(Fruit fruit) {
fruit.taste();
}
}
public class PolymorphicParameterPassing {
public static void main(String[] args) {
Apple apple = new Apple();
Orange orange = new Orange();
FruitTaster.tasteFruit(apple);
FruitTaster.tasteFruit(orange);
}
}
七、多态与类型转换
向上转型
将子类对象赋值给父类引用变量,称为向上转型。向上转型是自动的,它会丢失子类特有的方法,但可以调用父类和子类重写的方法。
向下转型
将父类引用变量转换为子类引用变量,称为向下转型。向下转型需要进行强制类型转换,并且在转换前需要使用 instanceof
运算符进行类型检查,以避免 ClassCastException
。
示例代码
class Vehicle {
void move() {
System.out.println("车辆移动");
}
}
class Car extends Vehicle {
@Override
void move() {
System.out.println("汽车行驶");
}
void park() {
System.out.println("汽车停车");
}
}
public class TypeCastingExample {
public static void main(String[] args) {
// 向上转型
Vehicle vehicle = new Car();
vehicle.move(); // 调用 Car 类重写的方法
// vehicle.park(); // 编译错误,丢失子类特有的方法
// 向下转型
if (vehicle instanceof Car) {
Car car = (Car) vehicle;
car.park(); // 可以调用子类特有的方法
}
}
}
八、接口与多态
接口的多态性
接口也可以实现多态。一个类可以实现多个接口,不同的类实现同一个接口的方法可以有不同的实现方式。通过接口类型的引用变量引用实现类的对象,同样可以实现多态。
示例代码
// 接口
interface ShapeInterface {
void draw();
}
// 实现类
class CircleInterface implements ShapeInterface {
@Override
public void draw() {
System.out.println("接口:绘制圆形");
}
}
class RectangleInterface implements ShapeInterface {
@Override
public void draw() {
System.out.println("接口:绘制矩形");
}
}
public class InterfacePolymorphism {
public static void main(String[] args) {
ShapeInterface circle = new CircleInterface();
ShapeInterface rectangle = new RectangleInterface();
circle.draw();
rectangle.draw();
}
}
九、课堂练习
练习 1
创建一个 Animal
抽象类,包含 eat
抽象方法。创建 Cat
、Dog
、Bird
类继承自 Animal
类,分别重写 eat
方法,输出不同的进食信息。编写一个 AnimalFeeder
类,包含一个 feed
方法,以 Animal
作为参数,调用 eat
方法。在 main
方法中创建不同动物对象,调用 AnimalFeeder
的 feed
方法。
练习 2
定义一个 MusicInstrument
接口,包含 play
方法。创建 Piano
、Guitar
类实现该接口,分别实现 play
方法。编写一个 MusicPlayer
类,包含一个 perform
方法,以 MusicInstrument
作为参数,调用 play
方法。在 main
方法中创建不同乐器对象,调用 MusicPlayer
的 perform
方法。
十、课程总结
重点回顾
- 多态的概念、作用和实现条件。
- 多态在方法调用和参数传递中的应用。
- 多态与类型转换(向上转型、向下转型)。
- 接口与多态的实现。
注意事项
- 在进行向下转型时,一定要使用
instanceof
进行类型检查,避免ClassCastException
。 - 合理运用多态可以提高代码的可扩展性和可维护性,但过度使用可能会导致代码的可读性降低。
十一、课后作业
作业 1
设计一个简单的游戏角色系统,包含 Character
抽象类,有 attack
和 defend
抽象方法。创建 Warrior
、Mage
、Archer
类继承自 Character
类,分别实现不同的攻击和防御方式。编写一个 GameManager
类,包含一个 battle
方法,以两个 Character
对象作为参数,模拟战斗过程。
作业 2
创建一个 ShapeArea
接口,包含 calculateArea
方法。创建 CircleArea
、RectangleArea
类实现该接口,分别实现计算面积的方法。编写一个 AreaCalculator
类,包含一个 printArea
方法,以 ShapeArea
作为参数,调用 calculateArea
方法并输出结果。在 main
方法中创建不同形状对象,调用 AreaCalculator
的 printArea
方法。