面向对象三大特性一一多态(polymorphism)
package com.bjsxt.oop.polymorphism;
public class Animal {
public void voice(){
System.out.println("动物叫声");
}
}
class Cat extends Animal{
public void voice(){
System.out.println("喵喵喵");
}
}
class Dog extends Animal{
public void voice(){
System.out.println("汪汪汪");
}
}
class Pig extends Animal{
public void voice(){
System.out.println("吭哧吭哧");
}
}
package com.bjsxt.oop.polymorphism; /**引用变量的2中类型
* 1,编译时类由声明事类型决定
* 2,运行时类型 由实际传入的对象类型决定
*
*
* 三个必要条件
* 要有继承
* 要有重写
* 父类引用指向子类对象
* @author Administrator
*
*/
public class Test {
/*如果没有多态,我们需要把每个子类的叫的方法写一遍,重载动物叫声方法 显然不方便
public static void testAnimalVoice(Cat c){
c.voice();
public static void testAnimalVoice(Dog d){
d.voice();
public static void testAnimalVoice(Pig p){
p.voice();
}*/
//使用多态就很简单 编译时类由声明事类型决定
public static void testAnimalVoice(Animal a){
a.voice();
}
public static void main(String[] args) {
//运行时类型 由实际传入的对象类型决定
/*父类引用指向子类对象
Cat c = new Cat();
Animal a = c;
我们写成下面这样
*/
Animal c = new Cat();
Animal d = new Dog();
Animal p = new Pig();
testAnimalVoice(c);
testAnimalVoice(d);
testAnimalVoice(p); }
}
我们试着重写方法
我们每一个动物,重写一个属于自己的方法;
package com.bjsxt.oop.polymorphism;
public class Animal {
public void voice(){
System.out.println("动物叫声");
}
}
class Cat extends Animal{
public void voice(){
System.out.println("喵喵喵");
}
public void catchMouse(){
System.out.println("猫抓老鼠");
}
}
class Dog extends Animal{
public void voice(){
System.out.println("汪汪汪");
}
public void seeDoor(){
System.out.println("狗看门");
}
}
class Pig extends Animal{
public void voice(){
System.out.println("吭哧吭哧");
}
public void sleep(){
System.out.println("猪在睡觉");
}
}
class Tiger extends Animal{
public void voice(){
System.out.println("吼吼吼");
}
public void eat(){
System.out.println("老虎在吃饭");
}
}
我们试着 调用一下
package com.bjsxt.oop.polymorphism; /**引用变量的2中类型
* 1,编译时类由声明事类型决定
* 2,运行时类型 由实际传入的对象类型决定
*
*
* 三个必要条件
* 要有继承
* 要有重写
* 父类引用指向子类对象
* @author Administrator
*
*/
public class Test {
/*如果没有多态,我们需要把每个子类的叫的方法写一遍,重载动物叫声方法 显然不方便
public static void testAnimalVoice(Cat c){
c.voice();
public static void testAnimalVoice(Dog d){
d.voice();
public static void testAnimalVoice(Pig p){
p.voice();
}*/
//使用多态就很简单 编译时类由声明事类型决定
public static void testAnimalVoice(Animal a){
a.voice();
}
public static void main(String[] args) {
//运行时类型 由实际传入的对象类型决定
/*父类引用指向子类对象
Cat c = new Cat();
Animal a = c;
我们写成下面这样
*/
Animal c = new Cat();
Animal d = new Dog();
Animal p = new Pig();
Animal t = new Tiger();
testAnimalVoice(c);
testAnimalVoice(d);
testAnimalVoice(p);
testAnimalVoice(t); //我们在我们重写了很多类的方法 我们试着调一下
//c.cathMouse(); 报错The method cathMouse() is undefined for the type Animal
//咦?说我们的抓老鼠的方法在Animal类里没定义 我让猫抓老鼠和你Animal有什么关系? 原来编译器不通过(编译器没那么智能,你传什么对象他就是啥了你得声明)是因为
//编译器 只认证不认人 比如 你掉方法 c.cathMouse(); c是什么呢? Animal c = new Cat(); c的前面 类型写的是Animal 你就是Animal类型
//既然 我们想让猫抓老鼠 那么 就强制转型被
//在编译器的角度看c是Animal 类型我们强制转换(Cat)然后 用 新的Cat c1来接受新的对象
Cat c1 = (Cat)c;
c1.catchMouse();
Dog d1=(Dog)d;
d1.seeDoor();
Pig p1 = (Pig)p;
p1.sleep();
Tiger t1 = (Tiger)t;
t1.eat();
//能把老虎转成猫吗?
Cat c2 = (Cat)t;
c2.catchMouse();//通过了,再次证明编译器死板
//跑起来报错Exception in thread "main" java.lang.ClassCastException: com.bjsxt.oop.polymorphism.Tiger cannot be cast to com.bjsxt.oop.polymorphism.Cat
//at com.bjsxt.oop.polymorphism.Test.main(Test.java:59)
//老虎不能转成猫
}
}
打印一下
喵喵喵
汪汪汪
吭哧吭哧
吼吼吼
猫抓老鼠
狗看门
猪在睡觉
老虎在吃饭
显然,这么做比较繁琐 ,不如做个逻辑判断,是啥就是啥。
//由于最后面的对象转型太繁琐,索性做一个逻辑判断
public static void testAnimalVoice(Animal a){
a.voice();
if(a instanceof Cat){
((Cat)a).catchMouse();
}else if(a instanceof Dog){
((Dog)a).seeDoor();
}else if(a instanceof Pig){
((Pig)a).sleep();
}else{
((Tiger)a).eat();
}
}
当然 里面也得做强制转换,否则,编译器不认,通不过。
public static void main(String[] args) {
//运行时类型 由实际传入的对象类型决定
/*父类引用指向子类对象
Cat c = new Cat();
Animal a = c;
我们写成下面这样
*/
Animal c = new Cat();
Animal d = new Dog();
Animal p = new Pig();
Animal t = new Tiger();
testAnimalVoice(c);
testAnimalVoice(d);
testAnimalVoice(p);
testAnimalVoice(t);
}
打印看一下结果
喵喵喵
猫抓老鼠
汪汪汪
狗看门
吭哧吭哧
猪在睡觉
吼吼吼
老虎在吃饭
对象转型可以使父类对象的引用可以指向子类对象,给程序带来了比较好的可扩展性:我们可以在一个方法的参数里面定义父类的引用,然后实际当中传的时候传的是子类的对象,然后我们再在方法里面判断这个传过来的子类对象到底属于哪个子类,然后再去执行这个子类里面的方法或者调用这个子类里面的成员变量,因此程序的可扩展性比单独定义好多个方法要好一些。
面向对象三大特性一一多态(polymorphism)的更多相关文章
- python 面向对象三大特性(封装 多态 继承)
今天我们来学习一种新的编程方式:面向对象编程(Object Oriented Programming,OOP,面向对象程序设计)注:Java和C#来说只支持面向对象编程,而python比较灵活即支持面 ...
- Java中面向对象三大特性之——多态
多态的概述: 多态是继封装.继承之后,面向对象的第三大特性. 生活中,比如跑的动作,小猫.小狗和大象,跑起来是不一样的.再比如飞的动作,昆虫.鸟类和飞机,飞起来也是不一样的.可见,同一行为,通过不同 ...
- python基础(25):面向对象三大特性二(多态、封装)
1. 多态 1.1 什么是多态 多态指的是一类事物有多种形态. 动物有多种形态:人,狗,猪. import abc class Animal(metaclass=abc.ABCMeta): #同一类事 ...
- C#面向对象三大特性:多态
什么是多态 公司最近为了陶冶情操,养了几种动物(Animal),有猫(Cat).狗(Dog).羊(Sheep),这些动物都有共同的特性,会吃(Eat).会叫(Shout),但是它们吃的不同,叫的也不同 ...
- 《Python》 面向对象三大特性之多态、封装
一.多态 1.什么是多态? 一个类表现出的多种状态:通过继承来实现的 在Java中的表现:在一个函数中需要给参数指定数据类型,如果这个地方可以接收两个以上类型的参数,那么这些类型应该有一个父类,这个父 ...
- 面向对象三大特性一一继承(inheritance)和组合(Composition)
记住2句话(常识),像个正常人思考! 1.“ is-a ”关系 用 继承! 学生是人,学生继承人这个类, 2. “has-a ”关系 用 组合!电脑有显卡,那么我们就在计算机类中增加显卡属性来复用显 ...
- 面向对象三大特性一一封装(encapsulation)
为什么要封装? 我们看电视,只要按一下开关和换台就行了.有必要了解电视的内部结构吗?有必要了解显像管吗? 封装是为了隐藏对象内部的复杂性,只对外公开简单的接口.便于外界调用,从而提高系统的可扩展性,可 ...
- Java基础-面向对象第三大特性之多态(polymorphism)
Java基础-面向对象第三大特性之多态(polymorphism) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.多态概述 多态是继封装,继承之后,面向对象的第三大特性,多态的 ...
- [.net 面向对象编程基础] (13) 面向对象三大特性——多态
[.net 面向对象编程基础] (13) 面向对象三大特性——多态 前面两节,我们了解了面向对象的的封装和继承特性,面向对象还有一大特性就是多态.比起前面的封装和继承,多态这个概念不是那么好理解.我们 ...
随机推荐
- MVC文件图片ajax上传轻量级解决方案,使用客户端JSAjaxFileUploader插件01-单文件上传
前段时间做了几个关于图片.文件上传的Demo,使用客户端Query-File-Upload插件和服务端Badkload组件实现多文件异步上传,比如"MVC文件上传04-使用客户端jQuery ...
- Android Studio 默认keystore 以及自定义keystore
我们使用Android Studio 运行或测试我们的app 它使用一个默认的debug.keystore进行签名. 这个默认签名(keystore)是不需要密码的,它的默认位置在 $HOME/.a ...
- C# 解析 json Newtonsoft果然强大,代码写的真好
C# 解析 json JSON(全称为JavaScript Object Notation) 是一种轻量级的数据交换格式.它是基于JavaScript语法标准的一个子集. JSON采用完全独立于语言的 ...
- 新玩具,React v16.7.0-alpha Hooks
周五看见React v16.7.0-alpha Hooks,今早起来看见圈里已经刷屏了Hooks,正好周末,正好IG和G2的比赛还没开始,研究下... 刚刚接触react时候非常喜欢用函数式组件,因为 ...
- bzoj 4929: 第三题
Description 给定n,b,c,d,e以及A0,A1,···,An−1,定义 xk=b×c^4k+d×c^2k+e f(x)=Sigma(Aix^i),0<=i<=n-1 请你求出 ...
- appium+python自动化38-adb shell按键操作(input keyevent)
前言 接着上篇介绍input里面的按键操作keyevent事件,发送手机上常用的一些按键操作 keyevent 1.keyevent事件有一张对应的表,可以直接发送对应的数字,也可以方式字符串,如下两 ...
- js中级总结
this问题: this是JavaScript的关键字 用途:指向某一个对象 如何判断this的指向 函数内:两种情况:1.以函数形式调用(不带 . 指向window ) 2.以方法形式调用 ...
- 为什么 JVM 不用 JIT 全程编译
从知乎扣出来的内容 https://www.zhihu.com/question/37389356 作者:RednaxelaFX链接:https://www.zhihu.com/question/37 ...
- 关于Linux服务器磁盘空间占满问题的解决方法
下面给大家分享一篇关于Linux服务器磁盘占满问题解决方法(/dev/sda3 满了),需要的的朋友参考下吧 下面我们一起来看一篇关于Linux服务器磁盘占满问题解决(/dev/sda3 满了), ...
- json串反转义(消除反斜杠)-- 转载
JSon串在被串行化后保存在文件中,读取字符串时,是不能直接拿来用JSON.parse()解析为JSON 对象的.因为它是一个字符串,不是一个合法的JSON对象格式.例如下面的JSON串保存在文件中 ...