eric-1001c

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            3 隨筆 :: 45 文章 :: 12 評論 :: 0 Trackbacks

          1)利用多態實現向上轉型upcase中的方法和域問題

          1. 一般的多態中的方法

           

          class Super {
              
          public void sayHello(){
                  System.out.println(
          "Super.sayHello()");
              }

              
          public void display(){
                  System.out.println(
          "Super.display()");
              }

          }

          class Sub extends Super {
              
          public void sayHello(){
                  System.out.println(
          "Sub.sayHell0()");
              }

              
          public void display(){
                  System.out.println(
          "Sub.display()");
              }

          }

          public class ExtendsTest {
              
          public static void main(String[] args) {
                  System.out.println(
          "*****Super: Super*****");
                  Super sup 
          = new Super();
                  sup.sayHello();
                  sup.display();
                  
                  System.out.println(
          "*****Sub:Sub*****");
                  Sub sub 
          = new Sub();
                  sub.sayHello();
                  sub.display();
                          
                  System.out.println(
          "*****Super:Sub*****");
                  Super sup2 
          = new Sub();
                  sup2.sayHello();
                  sup2.display();
              }

          }

          //output
          *****Super: Super*****
          Super.sayHello()
          Super.display()
          *****Sub:Sub*****
          Sub.sayHell0()
          Sub.display()
          *****Super:Sub*****
          Sub.sayHell0()
          Sub.display()

          這是最簡單,最常見的多態的一種情形,方法是用public修飾的。導出類的方法覆蓋了基類的方法,當導出類向上轉型的后(sub-->super),sup2在加載類方法的時候,會檢查導出類是否有覆蓋該方法,如果有就調用導出類的方法,因此這里sup2.display(),sup2.sayHello()結果都是Sub的。在這種情況下最好是使用javase5的@Override注解.但如果基類的方法是private(也就是final),那又會出現什么情況呢?

          class Sub extends Super {
              @Override
              
          public void sayHello(){
                  System.out.println(
          "Sub.sayHell0()");
              }

              @Override
              
          public void display(){
                  System.out.println(
          "Sub.display()");
              }

          }

          public class Super {
              
          public void sayHello(){
                  System.out.println(
          "Super.sayHello()");
              }

              
          public void display(){
                  System.out.println(
          "Super.display()");
              }

              
          private void sayGoodbye(){
                  System.out.println(
          "Super.sayGoodbye()");
              }

              
          public static void main(String[] args) {
                  System.out.println(
          "*****Super: Super*****");
                  Super sup 
          = new Super();
                  sup.sayHello();
                  sup.display();
                  sup.sayGoodbye();
                  
                  System.out.println(
          "*****Sub:Sub*****");
                  Sub sub 
          = new Sub();
                  sub.sayHello();
                  sub.display();
          //        sub.sayGoodbye();   sub class cann't invoke the private method of superclass 
                          
                  System.out.println(
          "*****Super:Sub*****");
                  Super sup2 
          = new Sub();
                  sup2.sayHello();
                  sup2.display();
                      // inoke the mothd of super class
                  sup2.sayGoodbye();
              }

          }

          在這個例子中,主要是想體現出如果基類的方法是private的,導出類就不能繼承這個方法。在向上轉型中調用這個方法,能且僅能調用基類的private方法(當然要求main()在基類中調用,否則在基類以外的地方不能調用基類的private方法,這個列子正是如此)
          下面再看如果方法是static的呢

          class StaticSuper{
              
          public static void staticGet(){
                  System.out.println(
          "staticsuper.staticGet()");
              }

              
          public void dynamicGet(){
                  System.out.println(
          "staticsuper.dynamicGet()");
              }

          }

          class StaticSub extends StaticSuper{
              
          public static void staticGet(){
                  System.out.println(
          "staticsub.staticGet()");
              }

              
          public void dynamicGet(){
                  System.out.println(
          "staticsub.dynamicGet()");
              }

          }

          public class StaticPolymorphism {
              
          public static void main(String[] args) {
                  StaticSuper sup 
          = new StaticSub();
                  sup.staticGet();
                  sup.dynamicGet();
              }


          }

          //output
          staticsuper.staticGet()
          staticsub.dynamicGet()

          由這個例子可以知道在多態是不適用于static的方法的。也就是說在加載類的時候,編譯器調用static方法不會去檢查導出類是否對基類的static方法是否覆蓋,而是直接裝載基類的static方法。

          2)多態中的域

          class FieldSuper{
              
          public int field =0;
              
          public int getField(){
                  
          return field;
              }

          }

          class FieldSub extends FieldSuper{
              
          public int field =1;
              
          public int getField(){
                  
          return field;
              }

              
          public int getSuperField(){
                  
          return super.field;
              }

          }

          public class FiledPolymorphism {
              
          public static void main(String[] args) {
                  FieldSuper sup 
          = new FieldSub();//upcast
                  System.out.println("sup.field= "+ sup.field+
                          
          ", sup.getField()"+sup.getField());
                  
                  FieldSub sub 
          = new FieldSub();
                  System.out.println(
          "sub.field()= "+
                          sub.field
          + ", sub.getfield()= "+
                          sub.getField()
          +",sub.getSuperField() = "+
                          sub.getSuperField());
              }

          }
          //output
          sup.field= 0, sup.getField()1
          sub.field()= 1, sub.getfield()= 1,sub.getSuperField() = 0

          域在多態中是不會被覆蓋的,FielddSuper.field和FieldSub.field被分配了兩個不同的存儲空間,同時在向上轉型的時候,編譯器也不會向下去找導出類是否覆蓋類的域,因此sup.field()返回了FieldSuper的field而不是FieldSub的field。對于想在導出類中獲得基類的域,就得像例子那樣通過super方法來獲取

          總結:對于利用多態的向上轉型,編譯器先從向上轉型后的基類出發,找出要調用的元素。根據不同元素采取不同的策略,如果是域,static以及private的方法,則不會去檢查導出類是否覆蓋這些方法(其實是不能覆蓋的)而直接調用基類的;如果是public的方法則檢查導出類是否覆蓋,覆蓋了就會調用導出類的,否則調用基類的

           

          posted on 2007-07-11 13:53 Eric-1001c 閱讀(181) 評論(0)  編輯  收藏 所屬分類: ThinkingInJava
          主站蜘蛛池模板: 临猗县| 屯昌县| 虎林市| 肥东县| 民丰县| 平度市| 北海市| 新兴县| 潜山县| 务川| 巴中市| 威海市| 灯塔市| 新乐市| 余庆县| 福建省| 贵州省| 上蔡县| 米泉市| 宝山区| 桂平市| 宁强县| 凌海市| 沾化县| 巴里| 横峰县| 阳泉市| 泉州市| 衡东县| 留坝县| 延安市| 林周县| 永寿县| 涪陵区| 宁远县| 抚州市| 徐水县| 刚察县| 禄丰县| 衡南县| 额济纳旗|