Java 学习之 多态性的理解

一、多态的概念:

  1. 面向对象的三大特性:封装、继承、多态。从一定角度来看,封装和继承几乎都是为多态而准备的。
  2. 多态的定义指允许不同 class 的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用)     
  3. 实现多态的技术称为动态绑定(dynamic binding),是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。           即:程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。因为在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上,从而导致该引用调用的具体方法随之改变,即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性。
  4. 多态的作用消除类型之间的耦合关系
  5. 现实中,关于多态的例子不胜枚举。比方说按下 F1 键这个动作,如果当前在 Flash 界面下弹出的就是 AS 3 的帮助文档;如果当前在 Word 下弹出的就是 Word 帮助;在 Windows 下弹出的就是 Windows 帮助和支持。同一个事件发生在不同的对象上会产生不同的结果。

下面是多态存在的三个必要条件:

多态存在的三个必要条件
一、要有继承;
二、要有重写;
三、父类引用指向子类对象(即向上转型)

Java中多态的实现方式:1、接口实现;2、继承父类进行方法重写;3、同一个类中进行方法重载(这属于静态的,本不在我们的讨论范围内)。

对多态做个简单的总结:

指向子类的父类引用由于向上转型了,它只能访问父类中拥有的方法和属性,而对于子类中存在而父类中不存在的方法,该引用是不能使用的。若子类重写了父类中的某些方法,在调用该些方法的时候,必定是使用子类中定义的这些方法(动态连接、动态调用)。


二、示例验证并加深理解:

借助网上看来的一个例子做了些许调整,这里总结如下:

例子、

 class A {
    public String show(D obj) {
        return ("A and D");
    }


    public String show(A obj) {
        return ("A and A");
    } 


public void show1(){
 System.out.println("----------A.show--------");
//next();
}
public void show2(){
 System.out.println("----------A.show2--------");
next();
}


public void next(){
//super.show1();
 System.out.println("----------A.next--------");
}


}


 class B extends A{
    public String show(B obj){
//重写加重载???????
//不,我感觉这对B来说是一个全新的方法,跟A无关
        return ("B and B");
    }
    
    public String show(A obj){
//重写
        return ("B and A");
    } 


public void show2(B obj){
//重写加重载???????
//不,我感觉这对B来说是一个全新的方法,跟A无关
//super.show1();
System.out.println("----------B.show2--------");
}
public void show1(){
//super.show1();
System.out.println("----------B.show--------");
//next();
}


public void next(){
//super.show1();
System.out.println("----------B.next--------");
}
}


 class C extends B{


}


 class D extends B{


}


public class Test {
    public static void main(String[] args) {
        A a1 = new A();
        A a2 = new B();
        B b = new B();
        C c = new C();
        D d = new D();
        a2.show1();
a2.show2();
        System.out.println("1--" + a1.show(b));
        System.out.println("2--" + a1.show(c));
        System.out.println("3--" + a1.show(d));
        System.out.println("4--" + a2.show(b));
        System.out.println("5--" + a2.show(c));
        System.out.println("6--" + a2.show(d));
        System.out.println("7--" + b.show(b));
        System.out.println("8--" + b.show(c));
        System.out.println("9--" + b.show(d));      
    }
}



例子的输出结果如下:


----------B.show--------
----------A.show2--------
----------B.next--------
1--A and A
2--A and A
3--A and D
4--B and A
5--B and A
6--A and D
7--B and B
8--B and B
9--A and D



例子的出处:http://blog.csdn.net/thinkGhoster/article/details/2307001

这里就不多做解释了,只强调一点:

当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法。

注意分清楚重写与重载的概念。子类中只能重写父类的方法,所以方法名相同,但参数不同的方法对于子类而言都应该是新方法,这样理解,对4的输出结果就不感到意外了吧。



文章中有什么不当之处请大家批评指正,共同进步嘛!










  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值