JAVA基础----多态

来源:互联网 发布:com域名注册查询 编辑:程序博客网 时间:2024/05/14 17:43

多态:

概念: 

一个事物的多种形态


多态前提和体现


1.有继承关系或者实现关系


2.有方法重写


3.有父类引用指向子类对象


//父类public class Fu {<span style="white-space:pre"></span>public void show(){<span style="white-space:pre"></span>System.out.println("Fu---show-run");<span style="white-space:pre"></span>}}//子类public class Zi extends Fu{//覆盖了父类的show方法<span style="white-space:pre"></span>public void show(){<span style="white-space:pre"></span>System.out.println("Zi----show-run");<span style="white-space:pre"></span>}}public class Demo {<span style="white-space:pre"></span>public static void main(String[] args) {<span style="white-space:pre"></span>//多态,父类引用指向子类对象<span style="white-space:pre"></span>Fu fu=new Zi();<span style="white-space:pre"></span>//调用show方法<span style="white-space:pre"></span>fu.show();<span style="white-space:pre"></span>}}


多态的好处:


1.提高了程序的维护性(由继承保证)

我的理解:
1.如果是多态的形式,可以利用子类的方法覆盖进行后期的维护


(因为在多态中子类的存在就是为了方法覆盖,

所以子类的代码会比较少,修改起来也比较清晰)


2.如果不是多态形式,只能在父类大批量的代码中进行修改




提高了程序的扩展性(由多态保证)

例如:

public void show(Object  obj){........}

如果一个方法接收的参数是一个父类,那么多态就已经形成了。

这个父类的所有子类都可以传进 这个方法。

泛型可以对此进行限定。


多态的弊端:
父类不能访问子类的特有方法


如果非要访问,向下转型(强转)
Zi  zi=(Zi) fu;//fu为多态对象


运行流程:


//父类public class Fu {int i = 6;Fu() {System.out.println("Fu---Run" + show());}public String show() {System.out.println("Fu---show-run" + i);return "Fu";}}//子类public class Zi extends Fu {int i = 8;Zi() {System.out.println("Zi---Run" + show());}// 覆盖了父类的show方法public String show() {System.out.println("Zi----show-run" + i);return "Zi";}}public class Demo {public static void main(String[] args) {// 多态,父类引用指向子类对象Fu fu = new Zi();// 调用show方法System.out.println("main" + fu.show());}}


main方法压栈后,用父类引用创建子类对象。

其实不用父类的引用程序的结果也是一样的。

创建子类对象可以理解为--调用子类的构造方法。

而子类的构造方法的第一个语句是super();

这是隐式的语句,和构造方法一样,你不写编译器帮你写。

它的存在造成了父类的构造方法先执行,

相当于子类的构造方法还没执行就掉用了父类的构造方法。

因此,父类构造方法压栈了,压栈之后它先执行super();

之后将 i 赋值为6。并且它的输出语句先得到执行。

但它的输出语句中用到了show()方法,它需要先从show()方法中得到返回值。

那么问题来了,到底调用哪一个show()方法?

这就要先说一个问题,是谁在掉用show()方法呢?

其实在show()的前面还隐藏了一个关键字-----this.

那this代表谁呢?

谁把父类的构造方法拉进栈的this就代表谁。

也就是说show()方法是子类在掉用,它也压栈了。

因为子类有show()方法,而且子类和父类还存在继承关系,所以方法被覆盖了。

而show()方法需要打印变量 i 但此时 子类中的 i 并没有被赋值,

子类的super();语句结束之后才会将 i 赋值为8,

子类和父类定义了相同的变量,需要super.i调用才会使用父类的变量。

所以打印结果为:

Zi----show-Run0

打印完之后因为show()方法是子类的,

所以将"Zi"返回给了父类构造方法的输出语句,show()方法弹栈,

所以打印的第二句话是:

Fu---RunZi

父类构造方法弹栈。

子类的super();执行完毕,将 i 的值赋值为8。

之后输出语句,调用show()方法(这里也隐藏这this,只不过子类与掉用者不存在继承关系,所以show()方法没变),

show()打印语句:

Zi----show-run8

打印之后将“Zi”返回给构造方法的输出语句-------弹栈

子类的构造方法打印:

Zi----runZi

子类弹栈;

main方法创建对象完毕,将new Zi();的地址值赋值给了fu;

main方法输出语句,因为调用了fu.show(),所以先打印:

Zi----show-run8

之后打印:

mainZi

main方法弹栈,程序结束。




本人见解未必真实


0 0
原创粉丝点击