`
incyanggan
  • 浏览: 34073 次
  • 性别: Icon_minigender_1
  • 来自: 广州
文章分类
社区版块
存档分类
最新评论

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


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics