# 多态
从某种意义上来说,封装和继承都是为了多态而准备的。
在Java中多态性可以分为两种不同的展现形式。
## 方法的多态性(编译时多态)
前面我们在两处地方提到了方法的多态性,一是方法的重载,还有是方法的重写。
> 方法重载多态性的意义在于一个方法名称有不同的实现;
> 方法重写多态性的实现在于,父类的一个方法,不同的子类可以有不同的实现
## 对象的多态性(运行时多态)
我们在Java程序中说的多态大多指的是运行时多态,所以我们后面直接用多态称呼。
> Java引用类型变量有两种类型:一种是编译时的类型,一种是运行时的类型。
* 编译的类型是由声明变量的时候决定的。
* 运行时类型由实际赋给该变量的对象决定。
```
//比如声明变量类型为Animal,实际赋给该变量的对象类型为Dog
Animal animal = new Dog();
```
**如果运行时的类型和编译时的类型不一致就会出现所谓的多态**。
* 首先编译时类型和运行时类型是一种父类和子类的关系。
* 多态最常用的场景就是子类重写父类的方法后,如果引用变量的类型为父类,而对象为子类,如果引用类型调用重写方法,会去执行子类定义的实现。
```java
//父类
public class Animal {
public void say(){
System.out.println("我是一个动物");
}
}
//子类1
public class Cat extends Animal{
public void say(){
System.out.println("我是一个猫");
}
}
//子类2
public class Dog extends Animal{
public void say(){
System.out.println("我是一个狗");
}
}
//测试类
public class Test {
public static void main(String[] args) {
//简单的子类继承 以及实例化对象
/**Dog dog=new Dog();
dog.say();
Cat cat=new Cat();
cat.say();**/
//多态测试
// 父类引用指向Dog子类的具体实现
Animal animal=new Dog();
animal.say();
// 更换实现
animal=new Cat();
animal.say();
}
}
```
## 引用类型的强制类型转换
```
//对象的转型
//对象向上转型:子类对象->父类对象 安全
//最大特点在于可以通过父类对象自动接收子类实例
Animal animal=new Dog();
//对象向下转型(引用类型的强制类型转换):父类对象->子类对象 不安全
// 向下转型
//必须向发生向上转型,才可以进行向下转型。
Dog dog=(Dog) animal;
dog.say();
// 向下转型 因为animal指向的是Dog具体实现 所以会报错
Cat cat=(Cat)animal;
cat.say();
```
编写Java程序时,引用变量只能调用他编译时的方法,而不能调用其运行时类型的方法。如果你必须要调用其运行时的类型,则需要进行强制类型转换。
强制类型转换是把大的类型转换为小的类型。
在我们的引用数据里,大的类型是父类,小的类型是子类。
只可能发生在子类和父类的关系中
## instanceof运算符
instance运算符的前一个操作数一般是引用数据类型变量,后一个操作数是类名(接口),它是用于判断前面的对象是否是后面的类、或者其子类。如果是的话,返回true。
> instanceof运算符一般用于在我们对引用数据类型进行强制类型转换之前判断使用。
> 避免在实际的运行过程中出现 ClassCastException
实例代码:
~~~
public class Client1 {
public static void main(String[] args) {
Animal tom = new Dog();
Animal mimi = new Cat();
Animal ani1 = new Animal();
if (ani1 instanceof Dog) { // 此处ani1的数据类型为 Animal 所以运算的结果为 false
Dog dog1 = (Dog) ani1;
System.out.println(dog1.getAge());
}
if (tom instanceof Dog) { // 此处tom运行时数据类型为 Dog 所以运算的结果为 true,可以进行转换
Dog dog2 = (Dog) tom; // 强制类型转换
dog2.setAge(20);
System.out.println(dog2.getAge());
}
tom.cry();
mimi.cry();
}
}
~~~
- JAVA基础
- JAVA开发准备
- JAVA介绍
- 开发JAVA的准备
- JAVA的运行原理
- JDK配置
- 我的第一个JAVA程序
- 类与对象
- 基础语言要素
- 数据类型
- eclipse的安装与使用
- 变量
- 直接量
- 运算符
- 流程控制
- 数组结构
- 面向对象
- 隐藏与封装
- 深入构造器
- 类的继承
- 多态
- 包装类
- final修饰符
- 抽象类
- 接口
- 内部类
- 设计模式
- 单例模式
- 工厂模式
- 集合框架
- 集合排序
- 常用类学习
- 异常处理
- Java基础测试
- 综合案例一
- JAVA高级
- 泛型
- 多线程
- 线程的创建
- 线程的生命周期
- 线程同步
- 线程通信
- 输入输出流(I/O编程)
- File文件操作
- 字节流与字符流
- 数据库
- 数据库介绍
- 数据库安装
- SQL
- 表的基本操作
- 修改数据语句
- 数据检索操作
- 多表数据操作
- 表结构设计
- 综合应用
