/** * 多态在实际开发中的作用,以下以“主任喂养宠物”为例,说明多态的作用: * 1、分析:主人喂养宠物这个场景要实现需要进行类型的抽象: * --主人【类】 * 主人可以喂养宠物,所以主人有喂养的动作 * --宠物【类】 * 宠物可以吃东西,所以宠物有吃东西的动作 * * 2、面向对象编程的核心::定义好类,然后将类实例化为对象,给一个环境驱使,让各个对象之间协作起来形成一个系统 * * 3、多态的作用??? * 降低程序的耦合度,提高程序的扩展力 * 能使用多肽尽量就使用多态 * 父类型引用指向子类型对象 * * 核心:面向抽象编程,尽量不要面向具体编程。 */
public class Test {
public static void main(String[] args){
//创建主人对象
Master zhangsan=new Master();
//创建猫对象
Cat tom=new Cat();
//主人喂猫::主人是张三,韦德是猫,猫是tom
zhangsan.feed(tom);
//创建狗对象
Dog erha=new Dog();
//主人喂狗
zhangsan.feed(erha);
}
}
/**
* 主人类
*/
/**
* 这种方式没有运用到java语言中的多态机制,存在缺点:Master拓展性太差,因为只要添加一个新的宠物,Master就需要新建一个方法
public class Master {
//喂养宠物的方法
public void feed(Cat c){
c.eat();
}
public void feed(Dog d){
d.eat();
}
}
//Master和Dog、Cat这两个类型的关联度很强,耦合度高,扩展力差
*/
//降低程序的耦合度【解耦合】,提高程序的扩展力【软件开发的一个重要目标】
public class Master {
//喂养宠物的方法
public void feed(Pet pet){
pet.eat();
}
}
/**
* 宠物
*/
public class Pet {
public void eat(){}
}
/**
* 宠物狗
*/
public class Dog extends Pet{
//吃的方法
//喜欢吃骨头
public void eat(){
System.out.println("小狗正在吃骨头!");
}
}
/**
* 宠物猫
*/
public class Cat extends Pet{
//小猫爱吃鱼
public void eat(){
System.out.println("小猫正在吃鱼!");
}
}
2、
//动物类
public class Animal {
public void move(){
System.out.println("动物在移动!");
}
}
public class Bird extends Animal{
//重写父类继承过来的方法
public void move(){
System.out.println("鸟在飞!!");
}
/**
* 子类对象特有的行为/动作
*/
public void fly(){
System.out.println("Bird fly!!");
}
}
public class Cat extends Animal{
//重写父类继承过来的方法
public void move(){
System.out.println("猫在走路!");
}
//这个方法不是从父类继承过来的方法
//这个方法是子类对象特有的行为
public void CatchMouse(){
System.out.println("猫爪老鼠!!");
}
}
import java.util.concurrent.Callable;
/**
* 关于java语言当中的多态语法机制:
* 1、Animal、Cat、Bird三个类之间的关系:
* Cat继承Animal
* Bird继承Animal
* Cat 和 Bird之间没有继承关系
*
* 2、面向对象三大特征:封装、继承、多态
*
* 3、关于多态中涉及的几个概念:
* --向上转型(upcasting):子类转成父类称为:向上转型(自动类型转换)
* --向下转型(downcasting):父类转成子类称为:向下转型(强制类型转换)
* 无论是向上转型还是向下转型,两种类型都必须有继承关系。
* 没有继承关系编译不能通过。
*/
public class Test {
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();
//多态语法机制
/**
* 1、Animal和Cat之间存在继承关系,Animal是父类,Cat是子类
*
* 2、new Cat()创建的对象类型是Cat,a2这个引用的数据类型是Animal,可以看出他们进行了类型转换,
* 子类型转换成父类型,称为向上转型/upcasting,或者称为自动类型转换
*
* 3、java中允许这种语法,父类型引用(a2)指向子类型对象。
*/
Animal a2=new Cat();
/**
* 1、在程序运行阶段,JVM堆内存当中真实创建的对象是Cat对象,那么a2.move();在运行阶段一定会调用Cat对象move()方法,此时发生了程序的
* 动态绑定,运行阶段绑定。
* 2、无论Cat类有没有重写方法,在运行阶段一定调用的是Cat对象的move方法,因为底层的对象就是Cat对象
* 3、父类型的引用指向字类型的对象这种机制导致程序在编译阶段绑定和运行阶段绑定会产生两种不同的状态/形态。
* 这种机制可以称为多态语法机制。
*/
a2.move();
/**
* 需求:假设想让 Animal a2=new Cat();对象执行CatchMouse()方法,怎么办???
* a2无法直接调用,因为a2的类型是Animal。Animal中没有CatchMouse()方法
* 可以将a2强制类型转换为Cat类型
* a2的类型是Animal(父类),转换成Cat类型(子类),被称为向下转型/downcasting/强制类型转换
*
* 注意:::向下转型也需要两者之间具有继承关系,不然会出错。强制类型转换需要加强制类型转换符
*
* 什么时候需要向下转型呢???
* 当调用的方法是子类型中特有的,在父类型中不存在,必须进行向下转型,
*/
Cat c2=(Cat)a2;
c2.CatchMouse();
//父类引用指向子类对象【多态】
Animal a3=new Bird();
//以下程序编译没问题,但是不能运行
// Cat c3=(Cat)a3;
//Bird和Cat直接不存在继承关系,此时出现著名的异常:
//java.lang.ClassCastException
//类型转换异常,这种异常经常出现在“向下转型”/“强制类型转换”中。。。
if(a3 instanceof Cat) {//a3是Cat类型的对象
Cat c3 = (Cat) a3;
c3.CatchMouse();
} else if (a3 instanceof Bird) {//a3是Bird类型的对象
Bird b3=(Bird) a3;
b3.fly();
}
/**
* <<<<<<<<< Cat c3=(Cat)a3; >>>>>>>>>>>>
* 1、以上异常只会出现在“强制类型转换”中,也就是说“向下转型”存在隐患(编译过了,运行错了)-->->向上转型只要编译过了,运行肯定没问题 Animal a2=new Cat();
* 2、向下转型编译通过,运行可能错误 Animal a3=new Bird(); Cat c3=(Cat)a3;
* 3、怎么避免“java.lang.ClassCastException”呢???
* 使用instanceof运算符可以避免出现以上的异常。
* 4、instanceof运算符怎么用???
* --语法格式:
* (引用 instanceof 数据类型名)
* --以上运算符的执行结果类型是布尔类型,结果是turn/false
* --关于运算结果turn/false;
* 假设(a instanceof Animal)
* turn表示:
* a这个引用指向的对象是一个Animal类型
* false表示:
* a这个引用指向的对象不是一个Animal类型
*/
};
/**
* 一下程序为什么运行失败》???
* a2.CatchMouse();
* 因为程序在编译阶段检查a2的类型是Animal类型。
* 从Animal.class字节码文件中查找CatchMouse()方法,最终没有找到该方法,导致静态绑定失败,没有绑定成功,编译失败。不可能会运行。。
*/
}