Java多态

本文详细介绍了Java中的多态实现,包括向上转型、动态绑定机制、向下转型以及instanceof运算符。向上转型允许父类引用指向子类对象,但无法调用子类特有的方法。动态绑定能在运行时根据对象的类型调用相应方法。向下转型需注意类型匹配,否则可能产生运行时错误。此外,文章还探讨了抽象类和接口的应用,包括抽象类与接口的区别,以及接口的继承与实现。UML类关系表示部分阐述了泛化、实现、依赖、关联、聚合和组合的差异和应用场景。最后,文章讨论了内部类的种类、特点和应用场景,以及枚举在if和switch结构中的使用。
摘要由CSDN通过智能技术生成

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

向上转型

向上转型(隐式转型,自动转型):把一个子类对象转向为一个父类对象,父类引用指向子类实例在这里插入图片描述

向上转型和动态绑定机制

多态的实现可以借由向上转型和动态绑定机制来完成,其中,向上转型实现了将子类对象向上转型为父类类型;而动态绑定机制能识别出对象转型前的类型,从而自动调用该类的方法,两者相辅相成。在本节中,我们将从多角度总结,向上转型与动态绑定机制的特点和注意事项。

语法:

向上转型
又称为自动转型、隐式转型。即是父类引用指向子类实例,也表示子类的对象可以赋值给父类的对象。向上转型是安全的,因为任何子类都继承并接受了父类的非私有成员方法。

绑定机制
绑定就是将一个方法调用同一个方法所在的类连接到一起。Java中存在静态绑定和动态绑定两种。

其中,静态绑定是指在程序运行之前进行绑定(由编译器和链接程序完成的),也叫做前期绑定。 动态绑定则是指在程序运行期间由 JVM 根据对象的类型自动的判断应该调用哪个方法,也叫做后期绑定。

应用:

  • 向上转型

当一个子类对象向上转型父类类型以后,就被当成了父类的对象,所能调用的方法会减少,只能调用子类重写了父类的方法以及父类派生的方法,而不能调用子类独有的方法。

譬如:图(1)所示Pencil继承自Pen,经过图(2)完成向上转型后,图(3)的方法调用会报错:The method show() is undefined for the type Pen,即无法调用不属于Pen的show方法。

图1
(图1)

图2
(图2)
图3

(图3)

绑定机制
静态绑定的示例:

譬如:有一类 Human,它派生出来三个子类 Chinese 类、American 类和 British类,三个子类中都重写了父类中的方法 speak( ):void。

如下图所示,在测试类中用静态绑定的方式调用方法 speak( )。这种调用方式是在代码里指定的,编译时编译器就知道 c 调用的是 Chinese 的 speak( ),a 调用的是 American 的 speak( )。
在这里插入图片描述

动态绑定的示例:

如果此时我们在测试类中做以下改动:Human 类中随机生成 Chinese 类、American 类和 British 类的对象,则编译器将不能根据代码直接确定调用哪个类中的 speak( )方法,直到运行时才能根据产生的随机数 n 的 值来确定 human[i]到底代表哪一个子类的对象,这样才能最终确定调用的是哪个类中的 speak( )方法,这就是动态绑定。

在这里插入图片描述

向下转型

向下转型也交强制类型转换
向下转型:子类引用指向父类对象,必须进行强转,可以调用子类特有的方法
在这里插入图片描述

instanceof运算符

在这里插入图片描述

关于类型转换的应用问题

1、向上转型的有什么用处?直接创建子类对象不是更方便?

向上转型的语法:父类类型 父类引用 = new 子类类型(参数);

即:使用父类引用指向子类实例化对象,也称为自动转型或隐式转型。
此时,该引用只能访问子类继承或重写父类的方法,而不能直接访问子类特有的方法。向上转型多适用于,有多个同父子类共同应用的场景,此时,可以借由父类引用,根据实际需要,转型为特定的子类对象实现多态。

譬如:父类Person,有3个子类Chinese、French、Russian,类中分别重写了eat方法
在这里插入图片描述
在这里插入图片描述

此时,在测试类中,如果需设置方法实现对各子类eat方法的调用。

方案1:创建eatTest方法,设置参数为父类类型,利用向上转型,在main方法中调用时,分别直接传入子类即可。
在这里插入图片描述

运行结果:
在这里插入图片描述

方案2:分别设置3个eatTest的重载方法,分别设置参数为:Chinese、French、Russian,main方法不变,运行结果也与方案1相同。
在这里插入图片描述

由此可清晰看出,采用向上转型设置的方案更加简单灵活。如后续再新增加新的子类,也无需新增eatTest方法,非常方便。
在这里插入图片描述
在这里插入图片描述
2、为什么需要向下转型,直接实例化子类不是更简单?

向下转型一般是为了重新获得因为向上转型而丢失的子类特性而存在,因此,通常在向下转型前需要先进行向上转型,向下转型通常也会结合instanceof一起应用。

譬如:修改上一问题中的3个子类Chinese、French、Russian,类中分别新增各自独有的方法。
在这里插入图片描述

此时如需在测试类eatTest方法中,修改eatTest ,实现针对传入不同的参数分别调用各自独立方法,则可以参考如下代码
在这里插入图片描述

由此可见,借由向下转型,可以在灵活应用多态的基础上,同时兼顾子类的独有性,相较于直接创建子类实例,提高了代码加灵活性。

关于向下转型易出现错误总结

1、向下转型需在满足向上转型前提下进行

譬如:如下图所示代码中,父类Person及两个子类Chinese,French,子类中既有重写父类的方法,又有各自独立的方法。
在这里插入图片描述

测试类中:先经过向上转型设置one指向Chinese,后由French强转one,此时虽然编译不会报错,但会产生运行时异常。
在这里插入图片描述
在这里插入图片描述

因此:请注意,向下转型时,不允许转为非原始类型,即“哪来回哪去”

2、类型转换时的括号应用

接上面父类Person及两个子类Chinese,French代码,此时测试类中,先经过向上转型设置on

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java多态指的是同一个方法名可以根据不同的对象调用出不同的行为。具体来说,多态是一种面向对象编程的特性,实现多态的方式主要有两种:方法重载和方法覆盖。方法重载指的是在一个类中定义多个同名方法,但这些方法有不同的参数列表,编译器会根据参数列表的不同选择合适的方法进行调用。方法覆盖指的是子类重写父类的方法,使得在使用父类对象调用该方法时,实际调用的是子类中的方法。 多态的好处在于,它可以提高代码的灵活性和可扩展性。通过多态,我们可以为不同的对象提供不同的行为,从而使得程序更加具有扩展性。此外,多态还可以让程序的调用更加简洁、清晰,提高了代码的可读性和可维护性。 下面是一个简单的Java多态的例子: ```Java class Animal { public void makeSound() { System.out.println("动物发出声音"); } } class Cat extends Animal { public void makeSound() { System.out.println("猫发出“喵喵”的声音"); } } class Dog extends Animal { public void makeSound() { System.out.println("狗发出“汪汪”的声音"); } } public class PolymorphismExample { public static void main(String[] args) { Animal animal1 = new Animal(); Animal animal2 = new Cat(); Animal animal3 = new Dog(); animal1.makeSound(); // 动物发出声音 animal2.makeSound(); // 猫发出“喵喵”的声音 animal3.makeSound(); // 狗发出“汪汪”的声音 } } ``` 在上面的例子中,Animal是一个父类,Cat和Dog是Animal的子类。Animal类中定义了一个makeSound()方法,Cat和Dog类分别重写了这个方法。在main()方法中,我们创建了三个Animal类型的对象,并分别调用它们的makeSound()方法。由于animal2和animal3都是Animal类型的对象,但实际上它们分别是Cat和Dog类型的对象,因此在调用它们的makeSound()方法时,实际上是调用了它们各自的实现,也就是Cat类和Dog类中重写的makeSound()方法。这就是Java多态的表现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值