Java面向对象——多态

Eclipse中创建类时可快捷创建继承


关于Java语言当中的多态语法机制(概念)

/**
 *         1、Animal,Cat,Bird三者之间关系
 *             Cat继承Animal
 *             Bird继承Animal
 *             Cat和Bird之间没有继承关系
 * 
 *         2、面向对象三大特征:封装 继承 多态
 * 
 *         3、关于多态中设计到的几个概念:
 *             *向上转型(upcasting)
 *                 子类型-->父类型  又称:自动类型转换。
 * 
 *             *向下转型(downcasting)
 *                 父类型-->子类型  又称:强制类型转换。【需要加强制类型转换符】
 * 
 *             *无论是向上转型还是向下转型,两种类型之间必须要有继承关系。
 *              没有继承关系程序是无法编译通过的。
 */


 以前编写的代码:

public static void main(String[] args) {
		//以前编写的程序
		Animal a1 = new Animal();
		a1.move();
		
		Cat c1 = new Cat();
		c1.move();
		c1.catchMouse();
		
		Bird b1 = new Bird();
		b1.move();
		
	}

 使用多态语法机制:

		
		//使用多态语法机制
		Animal a2 = new Cat();

/**
         * 
         * 1、Animal和Cat之间存在继承关系,Animal是父类,Cat是子类
         * 2、Cat is an Animal
         * 3、new Cat(); 创建的类型是Cat, a2这个引用的数据类型是Animal,他们进行了类型转    换
         *      子类型转换成父类型,称为向上转型
         * 4、Java允许这种语法:父类型引用指向子类型对象。
         * 
         */  

理解:

class 人 {

        public void run(){

                System.out.println("锻炼身体");

        }

}

class 运动员 extends 人 {

        public void run(){

                System.out.println("比赛呢!");

        }

}

main(){

        人 李四 = new 人 ( ); 

        李四.跑步 ( );        //锻炼身体

        人 张三 = new 运动员 ( );

        张三.跑步 ( ) ;        //比赛呢!

}


 因此对于以下这段代码:


		a2.move();	//猫在走猫步

/**理解:
         * 1、以上程序可以编译通过,编译器检查a2这个引用数据类型为Animal,由于在Animal字节码当中有move()方法,编译通过
         *       这个过程称为静态绑定,编译阶段绑定。
         * 2、在运行阶段当中,JVM堆内存当中真是创建的对象是Cat对象,那么以下程序在运行阶段一定会调用Cat对象的move()方法,
         *       此时发生了程序的动态绑定,运行阶段绑定。
         * 3、无论Cat类有没有写move方法,运行阶段一定调用的是Cat对象的move方法,因为底层真实的对象是Cat对象
         */


但以下代码编译错误


    a2.catchMouse();

因为a2的类型为Animal类型(只有Cat类型中有catchMouse方法),从Animal字节码文件中查找catchMouse()方法,最终没有找到该方法

/**此时:
         * 需求:
         *     假设想让以上对象执行catchMouse()方法
         *         a2无法直接调用,因为a2的类型Animal中没有这个方法
         *         我们可以将a2强制类型转换为Cat类型
         *         a2的类型是Animal(父类),转换成Cat类型(子类),被称为向下转型/downcasting
         * 
         * 注:向下转型也需要两种类型之间有继承关系。不然编译报错。强制类型转化需要加强制类型转换符
         * 
         * 什么时候需要使用向下转型呢?
         *         当调用的方法或访问的属性是子类型中特有的,在父类型当中不存在
         * 
         */实现:

        Cat c2 = (Cat)a2;
		c2.catchMouse();

其过程类似:

		long x = 100L;
		int i = (int)x;

    Animal a3 = new Bird();
    Cat c3 = (Cat)a3;

/**分析:
         * 1、以上程序编译是没有问题的,因为编译器检测到a3引用的数据类型是Animal
         * Animal和Cat之间存在继承关系,并且Animal是父类型,Cat是子类型,语法合格
         * 2、程序在运行阶段出现异常,因为JVM堆内存中真实存在的对象是Bird类型,
         * Bird对象无法转换成Cat对象,因为二者之间不存在继承关系,
         * 此时出现著名异常: java.lang.ClassCastException类型转换异常
         * 这种异常总是在“向下转型时”发生。
         */

/**
         * 1、这种异常总是在“向下转型时”发生,也就是说“向下转型”存在隐患(编译过但运行错)。
         * 2、向上转型只要编译通过运行不会出问题。Animal a2 = new Cat();
         * 3、向下转型编译通过但运行可能会出问题。Animal a3 = new Bird(); Cat c3 = (Cat)a3;
         * 4、怎么避免ClassCastException异常?
         *         使用instanceof运算符可避免出现以上的异常
         * 
         * 5、如何使用instanceof?
         * 
         *         5.1语法格式:
         *             (引用 instanceof 数据类型名)
         *         5.2以上运算符的执行结果类型是布尔类型,结果可能是true/false
         * 
         *         5.3关于运算结果true/false:
         *             假设:(a instanceof Animal)
         *             true表示: a这个引用指向的对象是Animal类型。 
         *             false表示:a这个引用指向的对象不是Animal类型。
         * 
         *         6、java规范中要求:在进行强制类型转换之前,建议采用instanceof运算符进行判读,避免ClassCastException异常的发生
         *           这是一种编程的好习惯
         */

    Animal a3 = new Bird();

//当a3引用指向地对象确实是一个Cat时
		if(a3 instanceof Cat) {
			Cat c3 = (Cat)a3;
			c3.catchMouse();
		}else if(a3 instanceof Bird) {
			Bird b2 = (Bird)a3;
			b2.move();
		}
//结果:鸟儿在飞翔!

总结多态语法:

	public static void main(String[] args) {

		//父类型引用指向子类型
		//向上转型
		Animal a1 = new Cat();
		Animal a2 = new Bird();
		
		//向下转型【只要当访问子类对象当中特有的方法】
		if(a1 instanceof Cat) {
			Cat c1 = (Cat)a1;
		}
		
		if(a2 instanceof Bird) {
			Bird b1 = (Bird)a2;
		}
		
	
	}

多态语法的作用 


/**
 * 多态在实际开发中的作用,以下以主人喂养宠物为例:
 *     1、分析:主人喂养宠物这个场景的实现需要进行类型的抽象:
 *         -主人【类】
 *             -主人可以喂养宠物,所以主人有喂养的这个动作
 *         -宠物【类】
 *            -宠物可以吃东西,所以宠物有吃东西的这个动作
 *
 *    2、面向对象编程的核心:定义好类,然后将类实例化为对象,给一个环境驱使一下,让各个对象协作起来形成系统
 *
 *    3、多态的作用是什么?
 *        降低程序的耦合度,提高程序的扩展力。
 *        能使用多态尽量使用。
 *        父类型引用指向子类型
 *
 *    【核心】:面向抽象编程,尽量不要面向具体编程。
 *
 */

public class Cat {

	public void eat() {
		System.out.println("Cat is eating fish!");
	}
}

public class Dog {

	public void eat() {
		System.out.println("Dog is eating meat!");
	}
}

public class Master {
	
	public void feed(Cat c) {
		c.eat();
	}
	public void feed(Dog d) {
		d.eat();
	}
	
}

测试程序:

ublic class Test {

	public static void main(String[] args) {
		//创建主人对象
		Master zhangsan = new Master();
		
		//创建猫对象
		Cat Tom = new Cat();
		
		//主人喂养猫
		zhangsan.feed(Tom);
		
		//创建小狗对象
		Dog Amy = new Dog();
		
		//主人喂养小狗
		zhangsan.feed(Amy);
		
	}

}

/**
 * 这种方式没有使用Java语言当中的多态机制,存在缺点:
 *     Master的扩展力很差
 */

修改,创建一个新的Pet宠物类(父类),并让其他子类继承父类(extends

public class Pet {
	
	//宠物都可以吃东西
	public void eat() {
		
	}


public class Cat extends Pet{

	public void eat() {
		System.out.println("Cat is eating fish!");
	}
}
public class Dog extends Pet{

	public void eat() {
		System.out.println("Dog is eating meat!");
	}
}

此时修改Master类,使程序耦合度变强

public class Master {
	
	public void feed(Pet pet) {
		pet.eat();
	}
	
}

这样多态机制的使用使得未来在进行java软件开发时软件更新不必修改整个代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值