我们知道面向对象设计的三个特性是:
- 封装性:类中的属性使用private进行封装;
- 继承性:在目前类的已有结构基础上继续进行功能的扩充;
- 多态性:在继承性的基础上扩充而来的概念,指的就是类型的转换处理
多态的基本概念
在Java中多态性有着两种实现模式
- 方法的多态性
- 方法的重载:同一方法名称可根据传入参数的类型或个数不同实现不同功能的执行
- 方法的覆写:同一方法,子类可以进行不同的实现
- 对象的多态性(父子实例之间的转换处理,它有两种模式)
- 对象向上转型:由子类向父类转型,语法是:父类 父类实例 = 子类实例;(自动完成转换)
- 对象向下转型:子类 子类实例 = (子类)父类实例;(强制完成转换)
常用的是对象的向上转型,对于对象的向下转型往往都在使用子类特殊功能(子类可以对父类进行功能扩充)的时候。
对象向上转型
对象转型的处理属于多态性,而这一特性必须在继承性的基础上实现
示例:对象向上转型
package basis;
/**
* @author lkh
* @date 2020/8/15 16:56
* @description 类的多态性
*/
public class demo14 {
public static void main(String[] args) {
Message msg = new DataBaseMessage();//对象的向上转型
msg.print();//"Mysql数据库连接信息"
}
}
class Message {
public void print(){
System.out.println("hello java");
}
}
class DataBaseMessage extends Message{
@Override //表示这是一个覆写方法
public void print() {
System.out.println("Mysql数据库连接信息");
}
}
那么向上转型的用处是什么呢?
修改一下上面的程序
package basis;
/**
* @author lkh
* @date 2020/8/15 16:56
* @description 类的多态性
*/
public class demo14 {
public static void main(String[] args) {
fun(new DataBaseMessage());// 这一句就相当于 Message msg = new DataBaseMessage();
fun(new WebServerMessage());// Message msg = new WebServerMessage();
//Mysql数据库连接信息
//Web服务器连接信息
}
public static void fun(Message msg){ //不管哪一个子类都调用print()方法
msg.print();
}
}
class Message {
public void print(){
System.out.println("hello java");
}
}
class DataBaseMessage extends Message{
@Override //表示这是一个覆写方法
public void print() {
System.out.println("Mysql数据库连接信息");
}
}
class WebServerMessage extends Message {
@Override
public void print() {
System.out.println("Web服务器连接信息");
}
}
作用就是可以对参数进行统一的设计!但是为什么不使用重载来解决问题呢?
因为:在进行程序类设计的时候,除了满足当前要求外,还要做出可维护性的设计。若Message产生了大量的子类后就需要追加一个fun()方法重载。这样就对程序维护性造成很大影响
对象的向下转型
向下转型的主要特点在于需要使用一些子类自己特殊的定义处理
示例:对象向下转型
package basis;
/**
* @author lkh
* @date 2020/8/15 16:56
* @description 类的多态性
*/
public class demo14 {
public static void main(String[] args) {
System.out.println("正常状态下超人是普通人");
Person per = new SuperMan(); // 向上转型
per.print();
System.out.println("当有怪物的时候,超人变身");
SuperMan man = (SuperMan) per; //向下转型
System.out.println(man.fly());
}
}
class Person{
public void print(){
System.out.println("吃饭睡觉打豆豆");
}
}
class SuperMan extends Person {
public String fly(){
return "i can flay";
}
public String fire(){
return "i can fire";
}
}
注意:在向下转型之前一定要首先发生向上转型
错误代码:
public class demo14 {
public static void main(String[] args) {
System.out.println("正常状态下超人是普通人");
Person per = new Person(); // 不转型
per.print();
System.out.println("当有怪物的时候,超人变身");
SuperMan man = (SuperMan) per; //向下转型
System.out.println(man.fly());
}
}
分析:不能变身的人强行变身就会被消灭
instanceof关键字
通过分析发现,向下转型本身存在安全隐患的操作,所以为了保证向下转型的正确性,往往在转型前需要进行判断,判断某个实例是否是某个类的对象,就需要instanceof语法。
该判断返回一个boolean类型,如果是true表示实例是指定类对象
使用语法
Person per = new SuperMan(); // 向上转型
System.out.println(per instanceof Person); // true
Person per = new Person(); // 不转型
System.out.println(per instanceof SuperMan); // false
提醒:日后进行项目开发时,若想进行向下转型,先使用instanceof判断一次。
以上内容从阿里云大学学习整理而来