Polymorphism[多态]

简述:

面向对象多态性指的是:发送消息给某个对象,让该对象自行决定响应何种行为。

通过将子类对象引用赋值给超类对象引用变量来实现动态方法调用

多态的三个前提条件:

  • 多态发生在有继承关系的类之间
  • 子类要对超类方法进行重写
  • 父类引用指向子类对象

要了解多态,先了解casting(对象转型)的概念。

Casting[对象转型]

1.基类的引用类型变量可以是指向子类的对象。

2.一个基类引用不能访问子类对象新增加的成员(属性和方法 )

3.可以使用引用变量instaceof来判断该引用类型变量所“指向”的对象是否属于该类,或者该类的子类。

4. 子类对象可以作为基类对象使用,称为(upcasting)“向上转型”,反之,基类对象当做来使用称为(downcasting)“强制转换”。

实例

我们创建两个类,并且有继承关系,一个Animal类和Cat类

class Animal{

	//每种动物都有名字
public String name;
//对应初始化方法
Animal(String name){
this.name=name;
} }
class Cat extends Animal{

	//猫眼睛的颜色
public String eyesColor;
//对应初始化
Cat(String name,String eyesColor){
super(name);
this.eyesColor=eyesColor; }
}

然后我们在验证 "1.基类的引用类型变量可以是指向子类的对象"

public class Casting{

	public static void main(String[] args){

	System.out.println("-------------------------------");
//创建Animal引用
Animal coco=null;
//把子类对象赋给父类引用
coco=new Cat("mimi","black");//编译通过没问题
}

继续验证  

2.一个基类引用不能访问子类对象新增加的成员(属性和方法
 )  "

我们把两个类增加方法

class Animal{

	//每种动物都有名字
public String name;
//对应初始化方法
Animal(String name){
this.name=name;
}
//动物叫声
public void say(){ System.out.println("name: "+name); }
}
//猫
class Cat extends Animal{ //猫眼睛的颜色
public String eyesColor;
//对应初始化
Cat(String name,String eyesColor){
super(name);
this.eyesColor=eyesColor; }
public void miaow(){ System.out.println("猫叫");
}
}

我们用coco对象分别访问父类和子类的成员和方法

//coco调用Cat中所有的成员
coco.name="mici";//可以访问子类继承到的name变量
System.out.println(coco.name);//输出mici //coco.eyesColor="blue";
/*编译输出:cannot find symbol
说明父类引用看不到子类对象的成员,只能用父类Animal的视野看,
那就只能看见name咯
*/
        coco.say();//编译运行没问题
	//coco.miaow();
/*编译输出:cannot find symbol
同样是编译出错找不到成员,所以向上转型父类引用只能看见自己传下去的东西咯
*/

先面我们來用
instanceof 来测试

首先

instanceof

instanceof是Java、php的一个二元操作符(运算符),和==,>,<是同一类东西。由于它是由字母组成的,所以也是Java的保留关键字。它的作用是判断其左边对象是否为其右边类的实例,返回boolean类型的数据。可以用在继承中的子类的实例是否为父类的实现。

应用于上面的例子

全部代码,做了修改

//Have the courage to follow your heart and intuition.
//对象转型。向上转型
//1.基类引用可以指向子类引用
//2.基类引用不能访问子类新增加的成员(方法属性)
//3.可以用 instanceof判断引用类型是不是这个类或者子类 package me.animal;
class Animal{ //每种动物都有名字
public String name;
//对应初始化方法
Animal(String name){
this.name=name;
}
//动物叫声
public void say(Animal any){ System.out.println("name: "+any.name);
//判断是什么类型猫啊狗啊,然后调用子类相应的成员
if(any instanceof Cat){
Cat cat=(Cat)any;
System.out.println(" "+cat.eyesColor+" eyes");
}
else if(any instanceof Dog){
Dog dog=(Dog)any;
System.out.println(" "+dog.furColor+" fur"); } } }
//猫
class Cat extends Animal{ //猫眼睛的颜色
public String eyesColor;
//对应初始化
Cat(String name,String eyesColor){
super(name);
this.eyesColor=eyesColor; }
public void miaow(){ System.out.println("猫叫");
}
}
//狗
class Dog extends Animal{ //狗毛的颜色
public String furColor;
//对应初始化
Dog(String name,String furColor){ super(name);
this.furColor=furColor;
}
//狗叫的方法
public void bark(){
System.out.println("狗叫了...");
} }
public class Casting{ public static void main(String[] args){ System.out.println("-------------------------------");
//创建Animal引用
Animal coco=null;
//把子类对象赋给父类引用
coco=new Cat("mimi","black");//编译通过没问题 //coco调用Cat中所有的成员
coco.name="mici";//可以访问子类继承到的name变量
System.out.println(coco.name);//输出mici coco.say();//编译运行没问题 //coco.eyesColor="blue";
/*编译输出:cannot find symbol
说明父类引用看不到子类对象的成员,只能用父类Animal的视野看,
那就只能看见name咯
*/
//coco.miaow();
/*编译输出:cannot find symbol
同样是编译出错找不倒成员,所以向上转型父类引用只能看见自己传下去的东西咯
*/
coco. //创建猫狗对象
System.out.println("-------------------------------");
Cat nina=new Cat("nina","blue");
Dog hasx=new Dog("hasx","black");
Animal yoyo=new Animal("yoyo"); //用instanceof判断是不是对象属于类型
System.out.println("-------------------------------");
System.out.println("nina instanceof Cat = "+(nina instanceof Cat));//ture
System.out.println("nina instanceof Animal = "+(nina instanceof Animal));//true //System.out.println("hasx instanceof Cat = "+(hasx instanceof Cat));
/* 这样编译错误:inconvertible types
使用instanceof 前提必须要有继承关系,
*/ System.out.println("-------------------------------");
System.out.println("hasx instanceof Dog = "+(hasx instanceof Dog));//true
System.out.println("hasx instanceof Animal = "+(hasx instanceof Animal));//true //动物引用yoyo 判断关系
System.out.println("yoyo instanceof Animal = "+(yoyo instanceof Animal));//true
System.out.println("yoyo instanceof Cat = "+(yoyo instanceof Cat));//false
System.out.println("yoyo instanceof Dog = "+(yoyo instanceof Dog));//false System.out.println("coco instanceof Animal = "+(coco instanceof Animal));//true
System.out.println("coco instanceof Cat = "+(coco instanceof Cat));//false System.out.println("coco instanceof Dog = "+(coco instanceof Dog));//false
/*这行编译没错而且可以运行,因为引用类型coco是Animal,还是与Dog有继承关系*/ System.out.println("-------------------------------");
//向下转型,
Cat my=(Cat)coco;
//my引用类型是猫,猫的成员当然可以访问咯
System.out.println(my.eyesColor);
my.miaow(); //调用Animal创建的方法,可扩展行增强了
System.out.println("-------------------------------"); coco.say(coco);
coco.say(nina);
coco.say(hasx);
coco.say(yoyo); System.out.println("-------------------------------"); }

多态实例

经过上面对对象转型的认识,可以编写测试多态的代码

//一.多态测试
//多态三个条件:1.有继承 2.有重写 3.父类引用指向子类对象
package me.polymoph; //二.抽象方法就是用来重写的,1.继承下来的子类必须重写 2.抽象类不能不能new。3. //Final 1.Final的变量值不能改变 2.Final 的方法不能重写 3.Final的方法不能被继承
abstract class Animal{ //~ public void enjoy(){ //~ //动物高兴了叫
//~ System.out.println("我叫叫叫~~"); //~ }
//抽象类改写
abstract void enjoy(); }
//子类
class Dog extends Animal{ //狗高兴不一定叫,我狗跳墙,复写方法
public void enjoy(){ System.out.println("我狗跳墙"); }
}
class Cat extends Animal{ //猫高兴了,走猫步,复写方法
public void enjoy(){ System.out.println("我走猫步"); } }
class Wolf extends Animal{ //狼高兴了,我吃兔子
public void enjoy(){ System.out.println("我吃兔子"); } } //然后测试类
public class Polymoph{ public static void main(String[] args){ //创建动物对象,超类引用,赋予之类对象
Animal coco=new Dog();
//
coco.enjoy(); coco=new Cat();
coco.enjoy(); coco=new Wolf();
coco.enjoy(); /*输出:
我狗跳墙
我走猫步
我吃兔子 *///输出的是子类的方法 } }

作者:YangGan

出处:

http://blog.csdn.net/incyanggan

本文基于
署名 2.5 中国大陆
许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名Yanggan
(包含链接).

Java菜鸟学习笔记--面向对象篇(十八):对象转型&多态的更多相关文章

  1. Java菜鸟学习笔记--面向对象篇(十五):Wrapper Class包装类

    什么是包装类? 在Java里一切都是对象,除了Java中的基本数据类型(byte,short,int,long,char,float,double,boolean)不是面向对象的,这在实际使用时存在很 ...

  2. Java菜鸟学习笔记--面向对象篇(十六):Object类方法

    Object类 什么是Object类? Object类是所有Java类的祖先,每个类都使用 Object 作为超类,所有对象(包括数组)都实现这个类的方法Object类是类层次结构的根,Object类 ...

  3. Java菜鸟学习笔记()--面向对象篇(七):Wrapper Class包装类

    什么是包装类? 在Java里一切都是对象,除了Java中的基本数据类型(byte,short,int,long,char,float,double,boolean)不是面向对象的,这在实际使用时存在很 ...

  4. Java菜鸟学习笔记--数组篇(三):二维数组

    定义 //1.二维数组的定义 //2.二维数组的内存空间 //3.不规则数组 package me.array; public class Array2Demo{ public static void ...

  5. Java菜鸟学习笔记--数组篇(二):数组实例&args实例

    基本类型实例 //1.定义一个一维数组,先声明,在分配空间 int []number;//生命,没有初始化,number=null number=new int[5];//初始化为默认值,int默认值 ...

  6. Java菜鸟学习笔记--Exception篇(一):异常简介

    什么是异常(Exception)? 简述: 在运行过程中,应用程序可能遭遇各种严重程度不同的问题.异常提供了一种在不弄乱程序的情况下检查错误的巧妙方式.它也提供了一种直接报告错误的机制. 不同类型异常 ...

  7. Dynamic CRM 2013学习笔记(二十八)用JS动态设置字段的change事件、必填、禁用以及可见

    我们知道通过界面设置字段的change事件,是否是必填,是否可见非常容易.但有时我们需要动态地根据某些条件来设置,这时有需要通过js来动态地控制了. 下面分别介绍如何用js来动态设置.   一.动态设 ...

  8. Dynamic CRM 2013学习笔记(三十八)流程1 - 操作(action)开发与配置详解

    CRM 2013 里流程有4个类别:操作(action).业务流程(business process flow).对话(dialog)和工作流(workflow).它们都是从 setting –> ...

  9. 【Java学习笔记之二十八】深入了解Java8新特性

    前言: Java8 已经发布很久了,很多报道表明java8 是一次重大的版本升级.在Java Code Geeks上已经有很多介绍Java 8新特性的文章,例如Playing with Java 8 ...

随机推荐

  1. strip 使用命令

    使用 通过消除使用调试器的粘合剂和符号信息,减少扩展公共对象文件格式(XCOFF)对象文件大小. 语法 strip [ -V ] [ -r [ -l ] | -x [ -l ] | -t | -H | ...

  2. crm操作安全角色

    using System;     using Microsoft.Xrm.Sdk;     using Microsoft.Crm.Sdk.Messages;     using System.Co ...

  3. WeakReference and WeakHashMap

    弱引用通过WeakReference类实现,弱引用和软引用很像,但弱引用的引用级别更低.对于只有弱引用的对象而言,当系统垃圾回收机制运行时,不管系统北村是否足够,总会回收该对象所占用的内存.当然,并不 ...

  4. 清理收缩VMware虚拟机MacOS系统的vmdk文件大小

    屌丝行和差的主要标准,尽管持续性眼贪婪mbp.但是,从另一方面限制患有米,只是在虚拟机中播放MacOS.(我不会告诉你我的笔记本i5+120SSD+500HHD+12G内存,跑MacOS虚拟机一点不卡 ...

  5. Java多线程的~~~Lock接口和ReentrantLock使用

    在多线程开发.除了synchronized这个keyword外,我们还通过Lock接口来实现这样的效果.由Lock接口来实现 这样的多线程加锁效果的优点是非常的灵活,我们不在须要对整个函数加锁,并且能 ...

  6. c语言复杂声明解析

    这是个好东西,接触c语言好几年了,第一次看到这东西,惊喜万分. 先提供个分析案例,以后看方便 vector <int> * (*seq_array[]) (int )={func1,fun ...

  7. ASP.NET 5:初始化数据库

    ASP.NET 5:初始化数据库 1.初始化数据库 1.2目录 这不是专述模式/架构设计的帖子,架构搭建以讲解文章为目的,先不过多分层. 截这个图也是便于你对应下面找代码文件路径! 1.2代码 先控制 ...

  8. 学习Easyui

    学习Easyui 社区easyui 论坛:http://bbs.jeasyuicn.com API地址:http://www.jeasyuicn.com/api 简单桌面版:http://app.bt ...

  9. CodeIgniter框架文件结构

    转自网络:http://my.oschina.net/scholer/blog/99226 这个本来是很基础的东西,基本上用过CI的人都知道这些,原本是不消说的~但是因为毕业论文是关于CodeIgni ...

  10. 大约PF_RING/Intel 82599/透明VPN一些事

    接近崩溃的边缘,如今,在医院这篇文章地方的想法,小病,我宁愿不吃药瓶.一台笔记本电脑,但无法上网,我不称职.想知道的东西.唯一可用3G,不开的热点.由于没人给我报销流程.这个周末,我只有一天,由于下雨 ...