多态
概述
面向对象的三大特征:封装,继承,多态。
多态的形式:
父类类型 对象名称 = new 子类构造器;
接口 对象名称 = new 实现类构造器;父类类型的范围 > 子类类型范围的。
多态的概念:
同一个类型的对象,执行同一个行为,在不同的状态下会表现出不同的行为特征。多态的识别技巧:
对于方法的调用:编译看左边,运行看右边。
对于变量的调用:编译看左边,运行看左边。多态的使用前提:
(1) 必须存在继承或者实现关系。
(2) 必须存在父类类型的变量引用子类类型的对象。
(3) 需要存在方法重写。小结:
记住多态的形式,识别,概念等语法即可!
public class PolymorphicDemo {
public static void main(String[] args){
//cat zhaocai = new cat();
animals zhaocai = new cat();
zhaocai.run();
}
public static class cat extends animals{
@Override
public void run(){
System.out.println("猫在不停的跑");
}
}
public static class animals{
public void run(){
System.out.println("动物在不停的跑");
}
}
}
多态的优缺点
优势:
1.在多态形式下,右边对象可以实现组件化切换,业务功能也随之改变,
便于扩展和维护。可以实现类与类之间的解耦。
2.实际开发的过程中,父类类型作为方法形式参数,传递子类对象给方法,
可以传入一切子类对象进行方法的调用,更能体现出多态的扩展性与便利。劣势:
1.多态形式下,不能直接调用子类特有的功能。编译看左边!! 左边
父类中没有子类独有的功能,所以代码在编译阶段就直接报错了!
小结:
记住以上语法!
public class PolymorphicDemo {
public static void main(String[] args) {
// 父类类型 对象名称 = new 子类构造器;
Animal dlam = new Dog();
dlam.run(); // 对于方法的调用:编译看左边,运行看右边。
// dlam.lookDoor(); // 报错了,多态形式下,编译看左边,左边没有独有功能
Animal taidi = new Dog();
go(taidi); /重要功能
Animal tom = new Cat();
go(tom);
}
// 开发一个游戏 所有动物都可以进来比赛
public static void go(Animal d){
System.out.println("开始。。");
d.run();
System.out.println("结束。。");
}
}
class Dog extends Animal{
@Override
public void run(){
System.out.println("🐕跑的贼快~~~~!");
}
// 独有功能
public void lookDoor(){
System.out.println("🐶看门");
}
}
class Cat extends Animal{
@Override
public void run(){
System.out.println("🐱跑的飞快~~~~!");
}
// 独有功能
public void catchMouse(){
System.out.println("🐱抓🐀");
}
}
class Animal{
public void run(){
System.out.println("动物跑!");
}
}
引用类型的自动类型转换
1.小范围类型的变量或者值可以直接赋值给大范围类型的变量。
2.大范围类型的变量或者值必须强制类型转换给小范围类型的变量。
引用数据类型转换的思想是一样的:
父类类型的范围 > 子类类型的范围。
Animal Cat引用数据类型的自动类型转换语法:
1.子类类型的对象或者变量可以自动类型转换赋值给父类类型的变量。小结:
记住语法!
引用类型的自动类型转换并不能解决多态的劣势。
public class PolymorphicDemo {
public static void main(String[] args) {
// 1.引用类型的自动类型转换:小范围的对象赋值给大范围的变量
Animal a = new Cat();
// 2.引用类型的自动类型转换:小范围的变量赋值给大范围的变量
Cat c = new Cat();
Animal a1 = c;
}
}
引用类型的强制转换以及转换异常
引用类型强制类型转换的语法:
1. 父类类型的变量或者对象必须强制类型转换成子类类型的变量,否则报错!强制类型转换的格式:
类型 变量名称 = (类型)(对象或者变量)注意:有继承/实现关系的两个类型就可以进行强制类型转换,编译阶段一定不报错!
但是运行阶段可能出现:类型转换异常 ClassCastExceptionJava建议在进行强制类型转换之前先判断变量的真实类型,再强制类型转换!
变量 instanceof 类型: 判断前面的变量是否是后面的类型或者其子类类型才会返回true,小结:
有继承/实现关系的两个类型就可以进行强制类型转换,编译阶段一定不报错!
但是运行阶段可能出现:类型转换异常 ClassCastException
Java建议在进行强制类型转换之前先判断变量的真实类型,再强制类型转换!
变量 instanceof 类型: 判断前面的变量是否是后面的类型或者其子类类型才会返回true,
Animal a = new Wolf();
a.run();
// a.catchSheep(); // 报错!
这样就不能调用子类中父类没有的方法了。所以要强转。
Animal a = new Wolf();
a.run();
// a.catchSheep(); // 报错!
// 1.把动物类型的变量a 转换成 真实的狼类型
Wolf w = (Wolf) a;
w.catchSheep();
下面是具体应用例子
public class PolymorphicDemo {
public static void main(String[] args){
animals zhaocai = new cat();
if(zhaocai instanceof cat){
cat mimi = (cat)zhaocai;
mimi.run();
} else if (zhaocai instanceof dog) {
dog gougou = (dog) zhaocai;
gougou.run();
}
}
public static class cat extends animals{
@Override
public void run(){
System.out.println("猫在不停的跑");
}
}
public static class dog extends animals{
@Override
public void run(){
System.out.println("狗在不停的跑");
}
}
public static class animals{
public void run(){
System.out.println("动物在不停的跑");
}
}
}
多态和接口综合案例
拓展:面向对象思想设计一个电脑对象,可以接入2个USB设备
(鼠标,键盘: 实现接入,调用独有功能,拔出)。分析:
(1)提供2个USB设备。(USB设备必须满足:接入和拔出的功能)
(2)定义一个USB的接口(申明USB设备的规范必须是:实现接入和拔出的功能)
(3)开始定义2个真实的实现类代表鼠标标和键盘
(4)定义一个电脑类。
小结:
记住这些面向对象的综合设计案例。
多态和接口的综合应用实例代码如下:
public class demo {
public static void main(String[] args){
computer waixingren = computer.createcom();
//创建鼠标
Mouse xiaomi = Mouse.createmouse();
waixingren.install(xiaomi);
//创建键盘
Keyboard xiaomi_1 = Keyboard.createKey();
waixingren.install(xiaomi_1);
}
//电脑
public static class computer{
//安装usb的接口
public void install(USB usb){
usb.connect();
if(usb instanceof Mouse){
((Mouse) usb).doubleclick();
}else if(usb instanceof Keyboard){
((Keyboard) usb).keypush();
}
usb.unconnect();
}
public static computer createcom(){
return new computer();
}
}
//两个USB设备:鼠标,键盘
public static class Mouse implements USB{
private String name;
public Mouse(String name){
this.name = name;
}
//双击
public void doubleclick(){
System.out.println(name + "点击了两下");
}
@Override
public void connect(){
System.out.println(name + "连接成功");
}
@Override
public void unconnect(){
System.out.println(name + "断开连接");
}
public static Mouse createmouse(){
return new Mouse("小米鼠标");
}
}
public static class Keyboard implements USB{
private String name;
public Keyboard(String name){
this.name = name;
}
//按键
public void keypush(){
System.out.println("小米键盘敲击了两下");
}
@Override
public void connect(){
System.out.println(name + "连接成功");
}
@Override
public void unconnect(){
System.out.println(name + "断开连接");
}
public static Keyboard createKey(){
return new Keyboard("小米键盘");
}
}
}
interface USB{
void connect(); //接入
void unconnect(); //拔出
}