文章目录

  • 1.为什么需要多态?
  • 2.多态访问成员的特点:
  • 3.多态的有点&例题
  • 4.多态的缺点&解决办法
    • 1. 多态的缺点: 使用父类引用无法访问子类所特有的方法
    • 2.解决办法: 向下转型
      • 2.1 向上转型(自动转换)
      • 2.2 向下转型(强制转换)
      • 2.3 java.lang.ClassCastException
  • 5.实现主人与宠物玩耍功能

1.为什么需要多态?

面想对象的三大基本特点特点封装、继承、多态。下面通过一个例子说明为什么需要多态。比如单词cut,在医生口中的意思是动手术,在导演口中意思是暂停,在理发师口中意思是剪头发。
总结:生活中,同一个动作在不同环境下表现出来的不同状态;Java中: 同一个方法在不同的对象中体现出来不同的状态;内存中: 父类引用指向子类对象
多态的实现的必要条件:

  • 1.存在继承关系
  • 2.存在方法重写
  • 3.父类引用指向子类对象
class Man {public void cut() {System.out.println("我是man, 我也不知道怎么cut");}
}class Doctor extends Man {public void cut() {System.out.println("动手术");}
}class Director extends Man {@Overridepublic void cut() {System.out.println("暂停");}
}class Hairdresser extends Man {@Overridepublic void cut() {System.out.println("剪头发");}
}

现在创建一个对象

public class Duotaidemo01 {public static void main(String[] args) {Man m = new Doctor();m.cut();m = new Director();m.cut();m = new Hairdresser();m.cut();}//运行结果为动手术暂停剪头发}

从一定角度来看,封装和继承几乎都是为多态而准备的。

2.多态访问成员的特点:

  • 成员变量: 编译时期看左边的类型,如果左边类型中没有变量,编译报错
    运行时期看左边类型,左边类型的变量的值就是运行的结果
    编译看左边,执行看左边
  • 成员方法:
    编译看左边,执行看右边
  • 构造方法:
    多态访问子类构造方法会先访问父类构造方法
    帮助子类初始化父类继承过来的成员
  • 静态方法:
    编译看左边,执行看左边
    看对象:Fu fu = new Zi();
class Fu {int num = 10;//父类成员方法public void method() {System.out.println("Fu.method()");}// 父类静态方法public static void show() {System.out.println("Fu.show");}
}class Zi extends Fu {int num = 20;@Override//子类成员方法public void method() {System.out.println("Zi.method()");}// 子类静态方法public static void show() {System.out.println("Zi.show");}}

创建一个子类对象 Zi

public class DuoTaiDemo02 {public static void main(String[] args) {Fu fu = new Zi();System.out.println(fu.num); // 10fu.method();//Zi.method()fu.show();//Fu.show}
}

3.多态的有点&例题

  • 多态的优点
    1.简化了代码
    2.提高了维护性和扩展性
    例子:需求: 饲养员给不同的动物喂不同的食物
    //开闭原则: 对扩展开放,对修改关闭
class Feeder{// 给老虎喂肉
//  public void feedMeatToTiger(Meat m, Tiger t) {//      m.show();
//      t.show();
//  }// 熊猫喂竹子
//  public void feedBambooToPanda(Bamboo b, Panda p) {//      b.show();
//      p.show();
//  }// 利用多态/** Food f = new Meat();* Animals a = new Tiger();*/public void feed(Food f, Animals a) {f.show();a.show();}
}class Animals{public String name;public void show() {System.out.println("我是动物");}public String getName() {return name;}public void setName(String name) {this.name = name;}}class Monkey extends Animals {@Overridepublic void show() {System.out.println("我是" + getName());}
}class Banana extends Food {@Overridepublic void show() {System.out.println("我是" + getName());}
}class Bear extends Animals{@Overridepublic void show() {System.out.println("我是" + name);}
}class Tiger extends Animals{@Overridepublic void show() {System.out.println("我是" + name);}
}class Panda extends Animals{@Overridepublic void show() {System.out.println("我是" + name);}
}class Food{public String name;public void show() {System.out.println("我是食物");}public String getName() {return name;}public void setName(String name) {this.name = name;}}class Meat extends Food{public void show() {System.out.println("我是" + name);}
}class Bee extends Food{@Overridepublic void show() {System.out.println("我是" + name);}
}class Bamboo extends Food{public void show() {System.out.println("我是" + name);}
}

创建对象

public class DuoTaiDemo03 {public static void main(String[] args) {Feeder f = new Feeder();Meat m = new Meat();m.setName("五花肉");Tiger t = new Tiger();t.setName("东北虎");
//      f.feedMeatToTiger(m, t);f.feed(m, t);Bamboo b = new Bamboo();b.setName("大竹子");Panda p = new Panda();p.setName("大熊猫");
//      f.feedBambooToPanda(b, p);f.feed(b, p);Food food = new Banana();food.setName("香蕉");Animals an = new Monkey();an.setName("猴子");f.feed(food, an);}
}
//我是五花肉
//我是东北虎
//我是大竹子
//我是大熊猫
//我是香蕉
//我是猴子

4.多态的缺点&解决办法

1. 多态的缺点: 使用父类引用无法访问子类所特有的方法

2.解决办法: 向下转型

  • 基本类型存在自动类型转换和强制类型转换
  • 引用类型存在向上转型和向下转型
2.1 向上转型(自动转换)
  • 格式:<父类型> <引用变量名> = new <子类型>();
  • 特点:
    子类转为父类 父类的引用指向子类对象。理解为自动进行类型转换
    此时通过父类引用变量调用的方法是子类覆盖或继承父类的方法
    此时通过父类引用变量无法调用子类特有的属性和方法
2.2 向下转型(强制转换)
  • 格式:<子类型> <引用变量名> = (<子类型> )<父类型的引用变量>;
  • 特点:
    父类转为子类,父类引用转为子类对象。理解为强制类型转换
    在向下转型的过程中,如果没有转换为真实子类类型,会出现类型转换异常
2.3 java.lang.ClassCastException
  • 异常名称: 类型转换异常

  • 产生原因: 在向下转型的过程中,没有转换成真实的类型

  • 解决办法: 在每次向下转型之前做一个类型的判断

  • 类型判断的语法: instanceof
    左边对象 instanceof 类名 这个表达式的结果是boolean类型
    测试它左边的对象是否是它右边的类的实例

    多态的弊端可以使用instanceof关键字+向下转型来解决
    我们知道我们需要对父类的所有子类做逐一判断,违背了开闭原则

public class DuoTaiDemo04 {public static void main(String[] args) {//      Car c = new BMW();
//      c.run();// 想要访问BMW的fillOil,无法访问// 利用向下转型
//      BMW bmw = (BMW) c;
//      bmw.fillOil();
//
//      c = new Benz();
//      c.run();//      Benz benz = (Benz) c;
//      benz.leakOli();//       BMW bmw2 = (BMW) c;
//      bmw2.fillOil();//       System.out.println(c instanceof BMW);
//      System.out.println(c instanceof Benz);Car c = new Benz();c.run();c = new BYD();c.run();if (c instanceof Benz) {Benz benz = (Benz) c;benz.leakOli();} else if (c instanceof BMW) {BMW b = (BMW) c;b.fillOil();} else  if (c instanceof BYD) {BYD byd = (BYD) c;byd.electric();}Object obj = new BMW();}
}class Car {public void run() {System.out.println("Car.run()");}
}class BMW extends Car {@Overridepublic void run() {System.out.println("BMW.run()");}public void fillOil() {System.out.println("加油");}
}class Benz extends Car {@Overridepublic void run() {System.out.println("Benz.run()");}public void leakOli() {System.out.println("漏油");}
}class BYD extends Car {@Overridepublic void run() {System.out.println("BYD.run()");}public void electric() {System.out.println("充电");}
}
//Benz.run()
//BYD.run()
//充电

5.实现主人与宠物玩耍功能

问题:
实现主人与宠物玩耍功能 play
和狗狗玩接飞盘游戏。
和企鹅玩游泳游戏。
编写测试类测试
分析:
给Dog添加接飞盘方法catchingFlyDisc( )
给Penguin添加游泳方法swimming( )
给主人添加play(Pet pet)方法 sendPet(Pet pet)
思考:如果还需要再主人类中添加赠送宠物的方法呢?

 public class DuoTaiDemo05 {public static void main(String[] args) {Hoster hoster = new Hoster(5, 3, "老王");hoster.play(new Dog());hoster.play(new Penguin());hoster.sendPet(new Dog());hoster.sendPet(new Dog());hoster.sendPet(new Dog());hoster.sendPet(new Dog());hoster.sendPet(new Dog());hoster.sendPet(new Dog());System.out.println(hoster.getPenguinCount());hoster.sendPet(new Penguin());hoster.sendPet(new Penguin());hoster.sendPet(new Penguin());hoster.sendPet(new Penguin());}
}class Hoster {private int dogCount;private int penguinCount;private String name;public Hoster() {super();}public Hoster(int dogCount, int penguinCount, String name) {super();this.dogCount = dogCount;this.penguinCount = penguinCount;this.name = name;}public void play(Pet pet) {pet.play();if (pet instanceof Dog) {Dog dog = (Dog) pet;dog.catchingFlyDisc();} else if (pet instanceof Penguin) {Penguin penguin = (Penguin) pet;penguin.swimming();}}public void sendPet(Pet pet) {if (pet instanceof Dog) {dogCount --;if (dogCount < 0) {dogCount = 0;}System.out.println("还剩下" + dogCount + "只狗!!!");} else if (pet instanceof Penguin) {penguinCount --;if (penguinCount < 0) {penguinCount = 0;}System.out.println("还剩下" + penguinCount + "只企鹅!!!");}}public int getDogCount() {return dogCount;}public void setDogCount(int dogCount) {this.dogCount = dogCount;}public int getPenguinCount() {return penguinCount;}public void setPenguinCount(int penguinCount) {this.penguinCount = penguinCount;}public String getName() {return name;}public void setName(String name) {this.name = name;}}class Pet {public void play() {System.out.println("Pet.play()");}
}class Dog extends Pet {public void play() {System.out.println("Dog.play()");}public void catchingFlyDisc() {System.out.println("Dog.catchingFlyDisc()");}
}class Penguin extends Pet {@Overridepublic void play() {System.out.println("Penguin.play()");}public void swimming() {System.out.println("Penguin.swimming()");}
}

运行结果:
Dog.play()
Dog.catchingFlyDisc()
Penguin.play()
Penguin.swimming()
还剩下4只狗!!!
还剩下3只狗!!!
还剩下2只狗!!!
还剩下1只狗!!!
还剩下0只狗!!!
还剩下0只狗!!!
3
还剩下2只企鹅!!!
还剩下1只企鹅!!!
还剩下0只企鹅!!!
还剩下0只企鹅!!!

多态知识整理实现主人与宠物玩耍功能相关推荐

  1. 【0717作业】添加主人给宠物洗澡,添加主人带宠物玩耍,不同宠物玩耍的行为不同...

    宠物类 1 package com.pet; 2 3 /** 4 * tip:添加主人给宠物洗澡,添加主人带宠物玩耍,不同宠物玩耍的行为不同 父类-宠物类 2019-07-17 5 * 6 * @au ...

  2. 多态应用-主人与宠物玩耍案例

    1 package com.szxs.pet; 2 /** 3 * 宠物类 4 * @author 5 * 6 */ 7 public class Pet { 8 private String nam ...

  3. 编写程序模拟“主人”喂养“宠物”的场景,利用多态的思想!!!

    代码 /*2.1.多态练习题编写程序模拟"主人"喂养"宠物"的场景:提示1:主人类:Master宠物类:Pet宠物类子类:Dog.Cat.YingWu提示2:主 ...

  4. Java-使用多态实现主人给宠物投喂食物功能

    Java-使用多态实现主人给宠物投喂食物功能 1. Pet Class package cn.animal.output;import java.util.Scanner;/*** @author J ...

  5. Python介绍与特点(自学python知识整理)

    Python介绍与特点(自学python知识整理) Python 简介 Python 是一个高层次的结合了解释性.编译性.互动性和面向对象的脚本语言. Python 的设计: Python 是一种解释 ...

  6. Kali Linux渗透基础知识整理(四):维持访问

    Kali Linux渗透基础知识整理系列文章回顾 维持访问 在获得了目标系统的访问权之后,攻击者需要进一步维持这一访问权限.使用木马程序.后门程序和rootkit来达到这一目的.维持访问是一种艺术形式 ...

  7. 深度学习基础知识整理

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/kwame211/article/details/81165381 本文是在七月的BAT机器学习面试1 ...

  8. *Java软件开发面试知识整理*

    Java软件开发面试知识整理 围绕以下几点回答问题:是什么.为什么.什么时候用.项目实现.解决什么问题.遇到的困难 谈谈你对Java和C的理解? Java: 面向对象.Unicode:可以跨平台(JV ...

  9. python常用变量名_python基础知识整理

    Python Python开发 Python语言 python基础知识整理 序言:本文简单介绍python基础知识的一些重要知识点,用于总结复习,每个知识点的具体用法会在后面的博客中一一补充程序: 一 ...

最新文章

  1. Transformer大升级!谷歌、OpenAI联合推出分层模型,刷榜ImageNet32刷新SOTA
  2. couldn't find native method
  3. 解决python在eclipse运行正常在命令行里运行提示包导入错误
  4. 经典C语言程序100例之九六
  5. 工程搭建:搭建子工程之分布式id生成器
  6. 线性链表java实现_java实现线性单链表
  7. Advanced User Administration
  8. 硬盘的接口,总线,协议知识点总结
  9. 【华为2019年校园招聘】2019-5-8 软件题
  10. python指南针_Mircopython: 在BPIbit上制作指南针
  11. UFS开发板代码分析
  12. 数据挖掘:Apriori 关联规则分析算法原理分析与代码实现
  13. 基于Matlab的IMM雷达多目标跟踪
  14. android图形计算器,Desmos图形计算器
  15. 蓝牙认证(BQB、FCC)
  16. 金陵科技学院c语言校内题库,金陵科技学院校内二级复习题
  17. CAD梦想画图的“测量曲线长度”
  18. 防火墙添加ip白名单_如何增加网址白名单、IP白名单、策略白名单、协同防御白名单?...
  19. 认识电脑的各大组件 【主板、CPU、内存条、硬盘、显卡、显示器】
  20. JVM成神之路-JVM内存结构

热门文章

  1. 企业为什么要先上ERP?
  2. 仿网易新闻评论“盖楼”效果实现
  3. 2021年金属非金属矿山(地下矿山)安全管理人员考试内容及金属非金属矿山(地下矿山)安全管理人员考试报名
  4. 什么是Vue CLI(脚手架)?
  5. 从零教你实现一个小说和漫画在线阅读网站[附源码]
  6. 协程爬取整站豆瓣网络
  7. 赤手空拳如何成就百万富翁?——网络营销之七(第四招:百度文库+)
  8. Gephi使用详解 实现图可视化(janusgraph)
  9. 汉语言文学计算机考试内容及答案,河南自考汉语言文学专业《计算机实践》课程考试大纲...
  10. 外国语言文学类毕业论文文献包含哪些?