面向对象三大特性三(多态)

面向对象三大特性三(多态)

多态是面向对象的三大特征之一。

1.概念

多态一词的通常含义是指能够呈现出多种不同的形式或形态。而在程序设计术语中,它意味着一个特定类型的变量,可以引用不同类型的对象,并且能自动地调用引用的对象的方法。

也就是根据用到的不同对象类型,响应不同的操作。方法重写是实现多态的基础。通过下面的例子可以简单认识什么是多态。

public class Pet {
    public void toHospital() {
        System.out.println("宠物去医院");
    }
}
class Dog extends Pet {
    @Override
    public void toHospital() {
        System.out.println("狗去医院");
    }
}
class Bird extends Pet {
    @Override
    public void toHospital() {
        System.out.println("鸟去医院");
    }
}
class Test {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.toHospital();
        Bird bird = new Bird();
        bird.toHospital();
        Pet pet;
        pet = new Dog();
        pet.toHospital();
        pet = new Bird();
        pet.toHospital();
    }
}

多态意味着在一次方法调用中根据包含的对象的实际类型(即实际子类的对象)来决定应该调用哪个子类的方法,而不是由用来存储对象引用的变量的类型决定的。当调用一个方法时,为了实现多态操作,这个方法即是在父类中声明过的,也必须是在子类中重写过的方法。

2.使用

  • 方法重写是多态的基础
  • 多态中,变量引用的是哪个对象,就执行的是哪个对象中相对应的方法

3.类型转换

3.1向上转型

子类向父类转换称为向上转型。

向上转型的语法格式如下:

父类类型 引用变量名 = new 子类类型();

例如: Pet pet = new Dog();

之前介绍了基本数据类型之间的类型转换,

  1. 把int类型常量或变量赋值给double类型的变量,可以自动进行类型转换。

  2. 把double类型的常量或变量赋值给int类型的变量,必须进行强制转换。实际上在引用数据类型的子类和父类之间也存在着类型转换问题

Pet pet = new Dog(); // 子类转换成父类,也称为父类引用指向子类对象
pet.toHospital(); // pet 对象调用的是Dog类的toHospital() 方法,体
现了多态。

多态就是说一个父类可能有多个子类,每个子类都重写了父类的方法(每个子类都有不同的方法实现),当父类引用调用方法时,父类引用指向哪个子类,就调用哪个子类的方法,形成了父类引用调用相同的方法名称时,有不同的输出形态。

  • 子类继承父类,并且子类重写父类的方法。
  • 父类引用指向子类对象(父类引用可以指向任意一个子类的对象)。
  • 父类引用调用方法时,实际上调用的是子类的方法(父类指向哪个子类就调用哪个子类的方法),不同的子类有不同的方法实现,体现出同一个方法在不同子类中的不同形态的表现。

此外,调用的时候应当注意:

  • 父类只能调用子类从父类继承的方法或重写的方法。
  • 父类不能调用子类新增的方法。

3.2向下转型

前面已经提到,当向上转型发生后,将无法调用子类新增的方法。但是如果需要调用子类新增的方法,可以通过把父类转换为子类实现。

将一个指向子类对象的父类引用赋值给一个子类的引用,即将父类类型转换为子类类型,称为向下转型,此时必须进行强制类型转换。

向下转型的语法规则如下。

子类类型 引用变量名 = (子类类型) 父类类型的引用变量;

例如: Dog dog = (Dog)pet;

3.3instanceof 运算符

在向下转型过程中,如果不是转换为真实的子类类型,会出现类型转换异常。所以在Java中提供了instanceof运算符来进行类型转换的判断。

  • 使用instanceof时,对象的类型必须和instanceof后面的参数所指定的类有继承关系,否则会出现编译错误。
  • 在使用instanceof时,先判断获取的对象是否是某一类型,再做强制类型转换,然后再对对象进行操作。这是传统的写法,在Java 16的增强之后,对于instanceof的判断以及类型转换可以合二为一了
  • 此外,在Java中,可以使用getClass()方法来进行类型转换的判断。getClass()方法是Object类的一个方法,所有Java类都继承自Object类,因此它可以在任何对象上调用。

getClass()返回的是运行时类的Class对象,所以比较时要使用==运算符,而不是使用equals()方法。另外,使用getClass()方法进行类型转换的判断通常用于处理特定类型的对象,而不是用于处理继承层次结构的类型判断。在处理继承层次结构时,通常会使用instanceof运算符来进行更灵活和安全的类型检查。

4.多态的应用

  1. 从上面的例子不难发现,多态的优势非常突出。
  2. 可替换性:多态对已存在的代码具有可替换性。
  3. 可扩充性:多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。实际上新加子类更容易获得多态。
  4. 接口性:多态是父类向子类提供了一个共同接口,由子类来具体实现。
  5. 灵活性:多态在应用中体现了灵活多样的操作,提高了使用效率。
  6. 简化性:多态简化了应用软件的代码编写和修改过程,尤其在处理大量对象的运算和操作时,这个特点尤为突出和重要。

在多态的程序设计中,一般有以下两种主要的应用形式。

4.1使用父类作为方法的参数

public void goHospital(Pet pet) {
	pet.toHospital();
}

4.2使用父类作为方法的返回值

public Pet donateAnimal(String type){
    Pet pet=null;
    if("dog".equals(type)){
        pet=new Dog();
    }else if("bird".equals(type)){
        pet=new Bird();
    }else{
        pet=new Pet();
    }
    return pet;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值