文章目录
今日提要:多态(脑袋都要大了)
1.多态的定义
[1].早期绑定(编译期多态)
定义:指在程序编译阶段根据对象的静态类型来确定调用哪个方法。在编译期多态中,编译器根据对象的静态类型来决定调用哪个方法,而不是根据对象的实际类型来决定调用哪个方法。这种多态是在编译时期就确定的。
要多变态有多变态,嗯嗯,简称多态
其实也没有多神秘,其实就是方法重载 ;方法重载发生在编译阶段,不依赖对象的实际运行情况,灵活性差,但是可以提高程序的效率和安全性;
不过我们今天和以后要说的多态其实是后期绑定,不是一开始绑上这个,是后面才绑上的那个;
[2].后期绑定(运行时多态)
定义:它允许一个对象在不同的上下文中表现出不同的行为。具体来说,多态是指在一个类的继承关系中,子类可以对父类的方法进行重写,从而使得在调用这些方法时,根据实际对象的类型来决定调用的是哪个类的方法。
其实就是说说继承关系中的方法重写;我不明白为什么要把这么简单的事情用那么复杂的概念定义出来,难道是怕说错了,负什么什么责任么?
2.为什么要聊运行时多态
后面没有特别说明的多态,都指的是运行时多态,它为什么这么重要,因为一个非常简单的原因,运行时多态可以让我们的代码具有更高的可读性和可维护性,代码的调用只关注接口而不用去关注具体实现,也就是说我们的代码能够更模块化,从而可以降低代码的耦合度(这句不像人话的人话,以后慢慢解释);
3.多态的表现形式(已经说了,没有特别说明,咱们说的多态就是运行时多态)
[1].继承关系方法重写
这是多态的核心内容
几个要点:
- 继承关系,继承关系,继承关系,重要的事情说三遍;
- 子类父类定义的方法名必须相同;
- 参数列表必须相同;
- 返回值类型必须相同;
- 范围修饰符可以扩大或者相同:public > protected > default;
看段代码更好理解
java
class Animal{
protected void roam () {
System.out.println("动物在闲逛");
}
}
class Wolf extends Animal{
public void roam() {
System.out.println("狼在原地盘桓");
}
}
class Tiger extends Animal{
void roam() {//这个是错误的
System.out.println("老虎在奔跑");
}
}
父类方法是protected void roam ()
,子类狼的重写方法public void roam()
是正确的,子类老虎的重写方法void roam()
是错误的,因为默认访问范围权限小于父类的方法的访问范围权限;
现在可能你就要问了,为啥访问范围权限不提private呢?记住了,private(私有)不让继承,不让继承
现在来看一个完整的重写:
java
class Animal{
protected void roam () {
System.out.println("动物在闲逛");
}
}
class Wolf extends Animal{
public void roam() {
System.out.println("狼在原地盘桓");
}
}
class Tiger extends Animal{
public void roam() {
System.out.println("老虎在奔跑");
}
}
public class TestOne {
public static void main(String[] args) {
Animal a = new Animal();
Animal a1 = new Wolf();
Animal a2 = new Tiger();
a.roam();
a1.roam();
a2.roam();
}
}
输出结果:
java
动物在闲逛
狼在原地盘桓
老虎在奔跑
这就是所谓的多态,是不是很容易理解了,不过理解不是重点,是理解以后的应用
[2].一些简单的应用实例
来,上盘代码:
java
class Animal{
protected void roam () {
System.out.println("动物在闲逛");
}
}
class Wolf extends Animal{
public void roam() {
System.out.println("狼在原地盘桓");
}
}
class Tiger extends Animal{
public void roam() {
System.out.println("老虎在奔跑");
}
}
public class TestOne {
public static void main(String[] args) {
Animal[] aa = new Animal[2];
aa[0] = new Wolf();
aa[1] = new Tiger();
for (Animal dd : aa){
dd.roam();
{
}
}
看看这个Animal[] aa = new Animal[2];
眼熟不?不眼熟?再来看看这个String[] xx = new String[2];
多态数组也是引用数组哦,你可以当一个数组来使用
上面那段代码的输出结果:
java
狼在原地盘桓
老虎在奔跑
如果这时我们需要一个方法要调用不同的对象,需要把不同的对象当做参数来用,我们就可以写public void xxxx(Animal a){......}
这么个方法
来段代码
java
class Animal{
protected void roam () {
System.out.println("动物在闲逛");
}
}
class Wolf extends Animal{
public void roam() {
System.out.println("狼在原地盘桓");
}
}
class Tiger extends Animal{
public void roam() {
System.out.println("老虎在奔跑");
}
}
class Eat{
public void eatUp(Animal a) {
System.out.print("吃完饭以后,");
a.roam();
}
}
public class TestOne {
public static void main(String[] args) {
Eat ss = new Eat();
Animal a = new Animal();
Animal a1 = new Wolf();
Animal a2 = new Tiger();
ss.eatUp(a1);
ss.eatUp(a2);
}
}
输出结果:
java
吃完饭以后,狼在原地盘桓
吃完饭以后,老虎在奔跑
多态决定了,你可以根据不同的对象,输出不同的结果,这样可以让我们的代码灵活性更高,无论再增加多少个子类,都可以正确的输出,这就是意义所在了,Eat类根本不用考虑哪些子类是后加的还是原来就有的,都一样可以执行;
多态就说到这里,多态最直接的地方就是我们可以模块化设计自己的代码,增加代码的可扩展性和灵活性,还有就是模块的复用性