Java入门基础:Java多态考题解析之一(那些年的Java多态考题)

起因:为什么写这篇文章,是因为网上看到一道笔试题,作者的解析是错误的,所以在此探讨一下。

题目如下,选择以下代码的输出结果:

class A{    
    public String s = "A";    
    public void setS(String s){     
        this.s = s;     
    }     
    public String getS(){     
        return this.s;     
    }      
}    
     
public class B extends A{     
    public String s = "B";    
    public void setS(String s){     
        this.s = s;     
    }     
    public String getS(){     
        return this.s;     
    }    
    public static void main(String[] args){     
        A a = new A();     
        B b = new B();     
        a.setS("[AA]");     
        b.setS("[BB]");     
        a = b;    
        System.out.print(a.s);    
        System.out.print(b.s);     
        System.out.print(a.getS());     
        System.out.print(b.getS());     
    }    
}  

A.AB[AA][BB]
B.[AA][BB][AA][BB]
C.A[BB][BB][BB]
D.A[BB]][AA][BB]

跑一下代码,我们马上能够得出结果肯定是选C,但是为什么选C呢?

本题有三个关键点:

1、B继承了A类,但是A和B类中都同时定义了s成员变量

2、B类中的setS重写了A类中的setS方法

3、a = b这条语句的意义

解析:

第一个关键点:

B b = new B();其实存在两个s,在内存中小b引用的对象其实有两个s,父类的s=“A",子类的s=”B“,这个特性其实就是Java中的类的成员属性是静态绑定的,父类和子类中可以定义重名的成员变量,各自独立,不会覆盖,内存结构如下:

Java入门基础:Java多态考题解析之一(那些年的Java多态考题)_第1张图片

第二个关键点不用解释,Java多态技术的基础,存在继承和重写

第三个关键点,也是最重要的关键点就是a = b后的内存结构,此时new A()已经没有用了,此时a和b两个变量其实都指向了new B()的内存

Java入门基础:Java多态考题解析之一(那些年的Java多态考题)_第2张图片

首先,需要理解Java多态定义的前提,因为变量a是A类型的,只能访问它实际类型中的成员,所以:

 System.out.print(a.s);     // a.s此时访问的是b对象父类的s,就是创建b对象时初始化为父类A时的s
 System.out.print(b.s);     // b.s此时方法的是b对象B类定义的s,但是这个s被b.setS("[BB]")重新赋值为[BB]了,得到[BB]
 System.out.print(a.getS());    // 这里是因为多态机制,调用的是b对象B类定义的getS方法,返回b的s,[BB]
 System.out.print(b.getS());     // 这里就没啥可说的了,b调自己的方法,返回b的s,[BB]

以上就是此题完整解释,谢谢

 

 

你可能感兴趣的:(Java)