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)的更多相关文章

  1. python 面向对象三大特性(封装 多态 继承)

    今天我们来学习一种新的编程方式:面向对象编程(Object Oriented Programming,OOP,面向对象程序设计)注:Java和C#来说只支持面向对象编程,而python比较灵活即支持面 ...

  2. Java中面向对象三大特性之——多态

    多态的概述:  多态是继封装.继承之后,面向对象的第三大特性. 生活中,比如跑的动作,小猫.小狗和大象,跑起来是不一样的.再比如飞的动作,昆虫.鸟类和飞机,飞起来也是不一样的.可见,同一行为,通过不同 ...

  3. python基础(25):面向对象三大特性二(多态、封装)

    1. 多态 1.1 什么是多态 多态指的是一类事物有多种形态. 动物有多种形态:人,狗,猪. import abc class Animal(metaclass=abc.ABCMeta): #同一类事 ...

  4. C#面向对象三大特性:多态

    什么是多态 公司最近为了陶冶情操,养了几种动物(Animal),有猫(Cat).狗(Dog).羊(Sheep),这些动物都有共同的特性,会吃(Eat).会叫(Shout),但是它们吃的不同,叫的也不同 ...

  5. 《Python》 面向对象三大特性之多态、封装

    一.多态 1.什么是多态? 一个类表现出的多种状态:通过继承来实现的 在Java中的表现:在一个函数中需要给参数指定数据类型,如果这个地方可以接收两个以上类型的参数,那么这些类型应该有一个父类,这个父 ...

  6. 面向对象三大特性一一继承(inheritance)和组合(Composition)

    记住2句话(常识),像个正常人思考! 1.“  is-a ”关系 用 继承! 学生是人,学生继承人这个类, 2. “has-a ”关系 用 组合!电脑有显卡,那么我们就在计算机类中增加显卡属性来复用显 ...

  7. 面向对象三大特性一一封装(encapsulation)

    为什么要封装? 我们看电视,只要按一下开关和换台就行了.有必要了解电视的内部结构吗?有必要了解显像管吗? 封装是为了隐藏对象内部的复杂性,只对外公开简单的接口.便于外界调用,从而提高系统的可扩展性,可 ...

  8. Java基础-面向对象第三大特性之多态(polymorphism )

    Java基础-面向对象第三大特性之多态(polymorphism) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.多态概述 多态是继封装,继承之后,面向对象的第三大特性,多态的 ...

  9. [.net 面向对象编程基础] (13) 面向对象三大特性——多态

    [.net 面向对象编程基础] (13) 面向对象三大特性——多态 前面两节,我们了解了面向对象的的封装和继承特性,面向对象还有一大特性就是多态.比起前面的封装和继承,多态这个概念不是那么好理解.我们 ...

随机推荐

  1. POJ2127 LICS模板

    题目:http://poj.org/problem?id=2127 十分费劲地终于记录好了路径……用一个前驱. 这是 n^2 的LICS方法.其实就是 n ^ 2 log n 把“找之前的d [ j ...

  2. 3台服务器Redis高可用哨兵模式实现(转)

    http://www.linuxidc.com/Linux/2017-05/143521.htm

  3. js正则表达式30分钟入门教程

    2011-10-27 13:23:15 如何使用本教程 最重要的是——请给我30分钟,如果你没有使用正则表达式的经验,请不要试图在30秒内入门——除非你是超人 :) 别被下面那些复杂的表达式吓倒,只要 ...

  4. java IO包的其他类

    DataInputStream 与 DataOutputStream 记事本默认会查编码表,可能会显示成这样 读取 ByteArrayInputStream 与 ByteArrayOutputStre ...

  5. Heritrix3.x自定义扩展Extractor

    一.引言: Heritrix3.x与Heritrix1.x版本差异比较大,全新配置模式的引入+扩展接口的变化,同时由于说明文档的匮乏,给Heritrix的开发者带来困惑,前面的文章已经就Heritri ...

  6. MySQL MHA环境搭建

    MHA功能: 1,从故障的mysql保存二进制日志时间(binlog events);2,识别含有最新更新的slave:3,应用差异的中继日志(relay log)到其他的slave:4,应用从mas ...

  7. spring SOA architecture

    在谈这个之前,还得再说下SOA和平台.SOA做两件事情,一个是解耦并识别可重用的服务,一个是对服务进行灵活组装和编排满足业务需求,SOA核心是业务和技术的解耦,服务和能力的复用.而在IT领域的平台平台 ...

  8. 在win7/WINDOWS SERVER 2008 R2上安装 vmware POWERcli 6.5

    安装.NET Framework 4.6.2下载NDP462-KB3151800-x86-x64-AllOS-ENU.exe,安装安装PowerShell 4.0(5.0依赖4.0)下载Windows ...

  9. configure: error: You need a C++ compiler for C++ support.

    安装pcre包的时候提示缺少c++编译器 报错信息如下: configure: error: You need a C++ compiler for C++ support. 解决办法,使用yum安装 ...

  10. Koa 框架整理

    学习交流 Koa使用了ES6规范的generator和异步编程是一个更轻量级Web开发的框架,Koa 的先天优势在于 generator.由于是我个人的分享交流,所以Node基础.ES6标准.Web开 ...