• Java菜鸟学习笔记--面向对象篇(十八):对象转型&多态


     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 (包含链接).


  • 相关阅读:
    Dubbo支持的协议的详解
    db2 SQL6036N解决办法
    9-5 HTTP注解演示及注意事项讲解
    9-4 Feign之HTTP注解介绍
    9-3 Feign演示及Feign注解解析
    9-2 Feign环境准备
    9-1 Feign自我介绍
    8-30 Hystrix章节总结
    8-29 实战技巧:如何设置线程池
    8-28 Hystrix监控讲解与演示
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3228504.html
Copyright © 2020-2023  润新知