面向对象三大特性之多态(3)
1.什么是多态?
多态——多种形态?
书面知识上分为了:引用多态和方法多态。
什么是引用多态呢?
引用多态就是指:(1)父类的引用可以指向本类的对象;(2)父类的引用也可以指向子类的对象。
(补充说明一下,引用类型是指其数据存放在堆中的内存空间而不是栈,而我们的引用类型所存放的就是指向这块内存的地址。)
所以也不难看出,继承是多态的基础。
public class FirstDemo {
public static void main(String[] args){
People obj = new People(); //父类的引用可以指向本类的对象
People obj2 = new Student(); //父类的引用也可以指向子类的对象
}
}
那么什么又是方法的多态呢?
即我们创建了父类的引用指向子类的对象,调用的方法就是子类中重写的方法或着继承的方法。
(注意,父类是不可以调用子类中独有的方法,如果一定要这么做呢?当然也是有方法的:如何通过父类引用“调用”子类所独有的方法)
2.多态中的类型转换
首先分为两种:向上类型转换 和 向下类型转换。
1.向上类型转换:即从小类型到大类型,也就是前面写到的People obj2 = new Student(); 因为是等号右边赋值给左边,所以是小到大的转换,这种转换是没有风险的。
2.向下类型转换:大类型向小类型转换。
前面引用多态的时候讲到父类的引用可以指向本类也可以指向其子类,那么子类可不可以指向父类呢?答案是可以,但是存在一定的风险。
虽然我们可以用强制类型转换,但是我们看一下这种情况:
People obj = new Student();这句是不会有问题,但是Teacher obj2 = (Teacher) obj;虽然我们加了强制类型转换,编译器不会报错,但是运行还是会报错。因为即使我们使用了强制类型转换,但是编译器编译的时候也会发现,Teacher和Student是不同类型对象。
那么在编程过程中我们怎么避免这个风险呢?
我们可以使用instanceof关键字,在进行强制类型转换的时候先判断是不是同一类型,只有相同时,才进行转换。
3.使用多态有什么好处?
说实话,没有做过大项目,也没有到公式去实习,感觉很难体会到这些概念的真正意义所在。
网上很多解释:
1 消除类型之间的耦合关系 2可替换性 3 可扩充性 4 接口性 5灵活性 6 简化性
下面这篇文章可以帮助很好的理解一下多态的具体意义所在。
【超经典】Java多态有什么好处?怎样用?
4.补充:抽象类和接口
抽象类、接口 都还是与多态相关一些概念,放在这里一起理解下。
其实在以前学习java的过程中对这些概念都只是停留在文字,因为基本很少涉及,似乎知道怎么写类,了解基本的语法仿佛就够了。
但是前面又看了一下java的基础视频,对这些概念又有了新的理解,这里就简单记录一下。
4.1抽象类
先从抽象类的应用场景来看:
- 在某些情况下,父类只知道其子类应该包含哪些方法,但是不知道这些子类具体如何实现这些方法。
- 从多个具有相同特征的类中抽象出一个抽象类,以这个抽象类作为子类的模板,避免了子类设计的随意性。例如dog 和cat类,他们都有eat的方法,所以可以抽象出animal类,让cat和dog都继承于它,在animal中定义抽象的eat方法,然后在子类中分别去实现。
说到底,抽象类的目的就是规定子类必须实现某些方法,但是不关注实现细节。
抽象类的使用规则:(1)使用abstract定义抽象类;(2)使用abstract定义抽象方法,只有申明,无需实现。
【抽象类不一定包换抽象方法,但是包含了抽象方法的类是抽象类】
4.2接口
类是一种具体实现体,而接口定义了某一批类所需要遵守的规范(这里其实和抽象类用来约束子类相似),接口不关心这些类里的方法的实现细节,以及这些类的内部数据,它只规定这些类里面必须提供这些方法。
接口的使用规则:(1)使用interface定义(2)接口里面只能时抽象方法(3)接口可以继承多个接口(类只能继承一个类)。
//接口
public interface IPlayGame {
public void playGame();
}
//psp可以用来玩游戏
public class Psp implements IPlayGame {
@Override
public void playGame() {
System.out.println("Psp can be used to play game.");
}
}
//智能手机也可以玩游戏,因此IPlayGame接口可以理解为游戏机和
智能手机这些类共同需要遵守的规范
public class SmartPhone implements IPlayGame {
@Override
public void playGame() {
System.out.println("Smartphone can be used to play game.");
}
}