1. 面向对象的三大特征:封装,继承,多态
2. Anima,Cat,Bird三个类之间的关系:
a) Cat继承Anima
b) Bird继承Anima
c) Cat和Bird之间没有任何继承关系
d)
3. 关于多态中涉及到的几个概念:
a) 向上转型(upcasting)
i. 子类型—》父类型
ii. 又被称为:自动类型转换
b) 向下转型(downcasting)
i. 父类型—》子类型
ii. 又被称为:强制类型转换【需要加强制类型转换符】
4. 需要记忆:无论是向上转型还是向下转型,两种类型之间必须要有继承关系,没有继承关系,程序是无法编译通过的,以下通过代码和注释来解释。
/**
* 动物类
* @author
*/
public class Anima {
public void move(){
System.out.println("动物在移动");
}
}
/**
* 鸟儿类
* @author
* 继承父类方法
*/
public class Bird extends Anima{
//从父类继承过来的方法
public void move(){
System.out.println("鸟儿在飞翔")
}
}
/**
* 猫科类
* @author
* 继承父类方法
*/
public class Cat extends Anima {
//从父类继承过来的方法
public void move(){
System.out.println("猫在走猫步")
}
//不是从父类继承过来的语法
//这个方法是子类特有的行为【不是说所有动物都能抓老鼠】
public void catchMouse(){
System.out.println("猫抓老鼠");
}
}
/**
* 测试类
* @author
*
*/
public class AnimaTest {
public static void main(String[] args) {
//以前写的程序
Anima g=new Anima();
g.move();
Cat k=new Cat();
k.move();
k.catchMouse();
Bird r=new Bird();
r.move();
//使用多态语法机制
/**
* 1.Anima和Cat之间存在继承关系,Anima是父类,Cat是子类
* 2.new Cat()创建对象的类型是Cat,a2这个引用是数据类型是Anima,可见它们进行了类型转换
* 3.子类型转换成父类型,称为向上转型,或者称为自动类型转换
* 4.Java中允许这中语:父类型引用指向子类型对象
*/
Anima a2=new Cat();
/**
* 1.Java程序永远都分为编译阶段和运行阶段
* 2.先分析编译阶段,再分析运行阶段,编译无法通过,根本是无法运行的
* 3.编译阶段编译器检查a2这个引用的数据类型为Anima,由于Anima.calss字节码当中
* 有move()方法,所以编译通过了,这个过程我们称为静态绑定,编译阶段绑定,只有静态绑定之后才有后续运行
* 4.在运行阶段:JVM堆内存当中真正创建的是Cat对象,那么以下程序运行阶段,一定会调用
* Cat对象的move()方法,此时发生了程序的动态绑定,运行阶段绑定.
* 5.无论Cat类有没有重写move方法,运行阶段一定调用的是Cat对象的move方法,因为底层
* 真实对象就是Cat对象
* 6.父类型引用指向子类型对象这种机制导致程序存在编译阶段绑定和运行阶段绑定两种不同
* 的形态/状态,这种机制可以成为一种多态语法机制
*/
a2.move();
/**
* 分析以下方法为什么不能调用?
* 因为编译阶段编译器检查到a2的类型是Anima类型,从Anima.class字节码中查找catchMouse
* ()方法,最终没有找到该方法,导致静态绑定失败,没有绑定成功,也就是说编译失败了,别谈运行了
*/
//a2.catchMouse();
/**
* 需求:假设想让以上的对象执行catchMouse()方法.怎么办?
* a2是无法直接调用的,因为a2的类型是Anima,Anima中没有catchMouse()方法
* 我们可以将a2强制类型转换为Cat类型,a2的类型是Anima,转换为Cat类型(子类),
* 被称为向下转型/强制类型转换.
* 注意:向下转型也需要两种类之间的继承关系,不然编译报错,强制类型转换需要加强制类型转换符
*
* 什么时候需要向下转型呢?
* 当调用的方法是子类型中特有的,在父类型中不存在,必须进行向下转型.
*/
Cat c2=(Cat)a2;
c2.catchMouse();
//父类引用指向子类型对象[多态]
Anima a3=new Bird();
/**
* 1.以下程序编译是没有问题的,因为编译器检查到a3的数据类型是Anima,Anima和Cat之间
* 存在继承关系,并且Anima是父类型,Cat是子类型,父类型转换成子类型叫做向下转型,
* 语法合格
* 2.程序虽然编译通过了,但是程序在运行阶段会出现异常,因为JVM堆内存中真实存在的对象是Brid
* 类型,Bird对象无法转换为Cat对象,因为两种类型之间不存在继承关系,此时出现了著名的异常:
* 类型转换异常:java.lang.ClassCastException
* 这种异常总是在"向下转型"的时候会发生
*/
Cat c3=(Cat)a3;
/**
* 1.以上异常只有在强制类型转换的时候会发生
* 2.向下转型要编译通过,运行一定不会出错:Anima a2=new Cat();
* 3.向上转型编译通过,运行可能错误:Anima a2=new Cat();Cat c3=(Cat)a3;
* 4.怎么避免向下转型出现的异常呢?java.lang.ClassCastException
* 使用instanceof运算符可以避免出现以上的异常.
* 5.怎么使用instanceof运算符呢?
* 5.1:语法格式:(引用 instanceof 数据类型名)
* 5.2:以上运算符的执行结果类型是布尔类型,结果是true/false
* 5.3:假设:(a instanceof Anima)
* true:表示a这个引用指向的是一个Anima类型
* false:表示a这个引用指向的对象不是Anima类型
* 6.Java规范中要求,在进行强制类型转换之前,建议采用instanceof运算符进行判断,避免异常的发生
* 这是一种编程好习惯,不是必须的
*/
if(a3 instanceof Cat){ //如果a3指向的是Cat类型的对象
Cat c3=(Cat)a3;
//调用子类对象中特有的方法
c3.catchMouse();
}else if(a3 instanceof Bird){ //如果a3指向的是Bird类型的对象
Bird b2=(Bird)a3;
//调用子类中特有的方法
b2.arr();
}
}
5. 多态的作用是什么?
a) 降低程序的耦合度,提高程序扩展力
b) 能使用多态尽量使用多态
c) 父类型引用指向子类型对象
6. 核心:面向抽象编程,尽量不要面向具体编程