文章标题:剖析Java中的多态特性
文章内容
文章目录
- 多态
- 向上转型与向下转型
- 向上转型及重写
- 重写与重载的差异
- 动态绑定与静态绑定
- 用代码阐释多态概念
- 向下转型
- 多态的优势
- 总结
多态
- 多态的定义与意义:简单来讲,多态体现为“多种形态”,具体是指不同对象去完成同一任务时所展现出的不同结果或状态。举个例子,就如同一个人面对不同个体时会呈现出不一样的行为表现。
- 多态实现的三个条件:
向上转型与向下转型

向上转型及重写
- 向上转型的方式一:直接赋值
将子类对象赋予父类类型的引用,格式为:父类类型 引用名 = new 子类类型()
class Animal {
public String name;
public int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
public void eat() {
System.out.println(this.name + " 在进食 ");
}
}
class Dog extends Animal {
public Dog(String name, int age) {
super(name, age);
}
public void back() {
System.out.println(this.name + " 汪汪汪 ");
}
}
public class test {
public static void main(String[] args) {
// 向上转型
Animal animal = new Dog("小白", 3);
animal.eat(); // 调用父类的eat方法
}
}
- 向上转型的方式二:传参
- 向上转型的方式三:传返回值
- 重写的条件:当父类实现的方法无法满足需求时可进行重写,重写需满足以下条件:
- 方法的返回值、方法名、参数列表均相同。
- 子类中被重写方法的访问修饰限定符要大于等于父类的(权限大小关系:private < 默认的 < protected < public)。
- 被private修饰的方法不能被重写。
- 被static修饰的方法不能被重写。
- 被final修饰的方法不可重写,因其具有恒定性。
- 构造方法也不能被重写。
public final void eat() {
// ...
}
被重写方法的返回值类型需是父子关系。
重写指的是子类与父类中有同名方法,当子类对象赋予父类类型引用(向上转型)后,使用该对象调用方法时,调用的是子类的方法而非父类的方法,此过程称为动态绑定。
如下是子类重写父类eat方法的示例:
@override注解可用于提示重写是否正确,避免语法错误。
重写与重载的差异
Object类是所有类的父类,若Dog类重写了自身的toString方法,则会使用重写后的toString方法;若未重写,则调用父类的toString方法。
动态绑定与静态绑定
- 静态绑定:在编译阶段就确定调用的方法,例如重载。
- 动态绑定:在编译阶段无法确定,在运行阶段才确定调用的方法,例如重写。
用代码阐释多态概念
无法调用子类特有的方法,只能调用父类的方法,只有重写后才会调用子类同名方法(例如eat())。
向下转型
- 将父类对象赋予子类类型的引用。
- 向下转型存在不安全因素。
- 若animal引用的对象是Cat对象的实例,则转型成功;否则执行下方打印操作。
多态的优势
- 能够降低代码的圈复杂度,避免大量使用if-else语句(圈复杂度指一段代码中条件语句和循环语句的个数)。
不使用多态时,打印图形的代码示例:
class Shape {
public void draw() {
System.out.println("画图");
}
}
class Rect extends Shape {
@Override
public void draw() {
System.out.println("⬜");
}
}
class Cycle extends Shape {
@Override
public void draw() {
System.out.println("⚪");
}
}
class Flower extends Shape {
@Override
public void draw() {
System.out.println("❀");
}
}
class Test2 {
public static void drawShapes() {
Rect rect = new Rect();
Cycle cycle = new Cycle();
Flower flower = new Flower();
String[] shapes = {"cycle", "rect", "cycle", "rect", "flower"};
for (String shape : shapes) {
if (shape.equals("cycle")) {
cycle.draw();
} else if (shape.equals("rect")) {
rect.draw();
} else {
flower.draw();
}
}
}
public static void main(String[] args) {
drawShapes();
}
}
使用多态后的代码示例:
public static void main(String[] args) {
Shape[] shapes = {new Cycle(), new Rect(), new Cycle(), new Rect(), new Flower()};
// 向上转型
for (Shape shape : shapes) {
shape.draw();
}
}
- 可扩展性强,新增一种新形状时,使用多态的代码成本较低。
class Flower extends Shape {
public void draw() {
System.out.println("花!");
}
}
- 属性不存在多态性,当父类成员变量与子类成员变量同名时,通过父类引用只能访问父类的变量。
- 构造方法不存在多态性,因为不能重写,重写会导致构造逻辑混乱。
总结
- 多态主要包含以下三点内容:
- 向上转型的作用:是实现重写的前提,即将子类对象赋予父类类型的引用。
- 动态绑定的作用:是实现多态的基础,在编译阶段无法确定调用的方法,在运行阶段才确定调用的方法。动态绑定在编译时看似调用父类方法,但运行时实际调用的是子类重写父类的方法
© 版权声明
文章版权归作者所有,未经允许请勿转载。
相关文章
暂无评论...