`
uag
  • 浏览: 19335 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
最近访客 更多访客>>
社区版块
存档分类
最新评论

你真的理解了继承和多态吗

    博客分类:
  • JAVA
 
阅读更多
public class DoYouReallyUnderstandPolymorphism { 
   
   public static void main(String[] args) { 
        A a = new A(); 
        B b = new B(); 
        a.s = "[AA]"; 
        b.s = "[BB]"; 
        System.out.println(a.s);      // prints "[AA]" 
        System.out.println(b.s);      // prints "[BB]" 
        System.out.println(a.getS()); // prints "[AA]" 
        System.out.println(b.getS()); // prints "[BB]" 
        System.out.println("===================="); 
        a = b; // a now refers to object b 
        System.out.println(a.s);   // prints "[A]"  <<--1-- the class A copy 
        System.out.println(b.s);      // prints "[BB]" 
        System.out.println(a.getS()); // prints "[BB]" 
        System.out.println(b.getS()); // prints "[BB]" 
        System.out.println("===================="); 
        ((A)b).s = "[AA]"; // <<--2-- changes the class A copy in object b 
        System.out.println(a.s);      // prints "[AA]" <<--3-- class A copy changed 
        System.out.println(b.s);      // prints "[BB]" 
        System.out.println(a.getS()); // prints "[BB]" 
        System.out.println(b.getS()); // prints "[BB]" 
    } 
 
} 
 
class A { 
    String s = "[A]"; 
    String getS() { 
        return s; 
    } 
} 
 
class B extends A{ 
    String s = ""; 
    String getS() { 
        return s; 
    } 
} 

解释:
  直观的讲,我们很容易轻信当"a = b;"以后,变量a指向的对象是B类的b那个对象,自然a.s就应该等同于b.s,然而事实并非如此。当B继承A时,父类A的字段s并没有被B的字段s取代,而是保留了一份拷贝,所谓重写(Override),那是对方法而言的。于是,当我们new B()时,在实际创建的对象中,包含了两个版本的字段s,一个"[A]"(属于A类)一个""(属于B类)。而方法getS()只有一个版本。这就是在继承过程中字段和方法的区别。也就是说,重写的概念和字段无关。在第16行,我们通过a.s访问的是b这个对象中保留的A类的字段s;而在21行,我们改变的正是这个A类版本的s字段。

  多态的精髓在于动态确定对象的行为,而对象的行为体现在方法而非字段,字段代表的更多的是对象的状态。于是只有方法的多态而没有字段的多态。从上面的代码可以看出,不管你用什么类型的变量存放对象b的引用,最终调用的方法版本都是b的真实类型那个版本,这就是多态的威力。
分享到:
评论
1 楼 sunny_hu 2010-01-24  
看来,我应该继续学习继承和多态,我理解的还不够啊!!!

相关推荐

Global site tag (gtag.js) - Google Analytics