多态知识整理实现主人与宠物玩耍功能
文章目录
- 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只企鹅!!!
多态知识整理实现主人与宠物玩耍功能相关推荐
- 【0717作业】添加主人给宠物洗澡,添加主人带宠物玩耍,不同宠物玩耍的行为不同...
宠物类 1 package com.pet; 2 3 /** 4 * tip:添加主人给宠物洗澡,添加主人带宠物玩耍,不同宠物玩耍的行为不同 父类-宠物类 2019-07-17 5 * 6 * @au ...
- 多态应用-主人与宠物玩耍案例
1 package com.szxs.pet; 2 /** 3 * 宠物类 4 * @author 5 * 6 */ 7 public class Pet { 8 private String nam ...
- 编写程序模拟“主人”喂养“宠物”的场景,利用多态的思想!!!
代码 /*2.1.多态练习题编写程序模拟"主人"喂养"宠物"的场景:提示1:主人类:Master宠物类:Pet宠物类子类:Dog.Cat.YingWu提示2:主 ...
- Java-使用多态实现主人给宠物投喂食物功能
Java-使用多态实现主人给宠物投喂食物功能 1. Pet Class package cn.animal.output;import java.util.Scanner;/*** @author J ...
- Python介绍与特点(自学python知识整理)
Python介绍与特点(自学python知识整理) Python 简介 Python 是一个高层次的结合了解释性.编译性.互动性和面向对象的脚本语言. Python 的设计: Python 是一种解释 ...
- Kali Linux渗透基础知识整理(四):维持访问
Kali Linux渗透基础知识整理系列文章回顾 维持访问 在获得了目标系统的访问权之后,攻击者需要进一步维持这一访问权限.使用木马程序.后门程序和rootkit来达到这一目的.维持访问是一种艺术形式 ...
- 深度学习基础知识整理
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/kwame211/article/details/81165381 本文是在七月的BAT机器学习面试1 ...
- *Java软件开发面试知识整理*
Java软件开发面试知识整理 围绕以下几点回答问题:是什么.为什么.什么时候用.项目实现.解决什么问题.遇到的困难 谈谈你对Java和C的理解? Java: 面向对象.Unicode:可以跨平台(JV ...
- python常用变量名_python基础知识整理
Python Python开发 Python语言 python基础知识整理 序言:本文简单介绍python基础知识的一些重要知识点,用于总结复习,每个知识点的具体用法会在后面的博客中一一补充程序: 一 ...
最新文章
- Transformer大升级!谷歌、OpenAI联合推出分层模型,刷榜ImageNet32刷新SOTA
- couldn't find native method
- 解决python在eclipse运行正常在命令行里运行提示包导入错误
- 经典C语言程序100例之九六
- 工程搭建:搭建子工程之分布式id生成器
- 线性链表java实现_java实现线性单链表
- Advanced User Administration
- 硬盘的接口,总线,协议知识点总结
- 【华为2019年校园招聘】2019-5-8 软件题
- python指南针_Mircopython: 在BPIbit上制作指南针
- UFS开发板代码分析
- 数据挖掘:Apriori 关联规则分析算法原理分析与代码实现
- 基于Matlab的IMM雷达多目标跟踪
- android图形计算器,Desmos图形计算器
- 蓝牙认证(BQB、FCC)
- 金陵科技学院c语言校内题库,金陵科技学院校内二级复习题
- CAD梦想画图的“测量曲线长度”
- 防火墙添加ip白名单_如何增加网址白名单、IP白名单、策略白名单、协同防御白名单?...
- 认识电脑的各大组件 【主板、CPU、内存条、硬盘、显卡、显示器】
- JVM成神之路-JVM内存结构
热门文章
- 企业为什么要先上ERP?
- 仿网易新闻评论“盖楼”效果实现
- 2021年金属非金属矿山(地下矿山)安全管理人员考试内容及金属非金属矿山(地下矿山)安全管理人员考试报名
- 什么是Vue CLI(脚手架)?
- 从零教你实现一个小说和漫画在线阅读网站[附源码]
- 协程爬取整站豆瓣网络
- 赤手空拳如何成就百万富翁?——网络营销之七(第四招:百度文库+)
- Gephi使用详解 实现图可视化(janusgraph)
- 汉语言文学计算机考试内容及答案,河南自考汉语言文学专业《计算机实践》课程考试大纲...
- 外国语言文学类毕业论文文献包含哪些?