關於一道J@Whiz1.4的經典問題的說明

來源:互聯網
上載者:User

問題的提出:

 class Parent {       

       private void method1() {

              System.out.println("Parent's method1()");

        }

        public void method2() {

                System.out.println("Parent's method2()");

                method1();           // ①

        }

}

class Child extends Parent {

        public void method1() {

                System.out.println("Child's method1()");

        }

        public static void main(String args[]){

                Parent p = new Child();             // ②

                p.method2();        // ③

        }

在②處聲明了一個Parent類型的引用p,它指向一個Child對象;通常來說,p應該具有後綁定功能。③處調用method2(),這個method2()肯定是指從Parent類繼承而來的method2()。

 但問題是Parent類的method2()中,調用了method1(),這個method1()是誰的?Parent的,還是Child的?

 看起來挺難判斷的,但結果是調用了Parent的method1()?也許會問method1()不是Parent的一個私人成員嗎?Child對象怎麼能調用呢?

 請先看下面的例子,將得到解答——

例子一:

 

class Base5 {

       protected void doStuff1() {

              System.out.println("Base-doStuff1");

       }

       final void doStuff2() {

              System.out.println("Base-doStuff2");

       }

}

 

class Child5 extends Base5 {

       protected void doStuff1() {

              System.out.println("Child-doStuff1");

       }

       protected void doStuff2() {               // ④

              System.out.println("Child-doStuff2");

       }

      

       public static void main(String[] args) {

              Base5 c = new Child5();    

              c.doStuff1();

              c.doStuff2();        

       }

}

 

 

編譯結果如下:

 

D:/JavaEx/scjp/tst/tst18.java:14: doStuff2() in Child5 cannot override doStuff2() in Base5; overridden method is final

       protected void doStuff2() {

                       ^

1 error

 

 

由於Base5的doStuff2()是final的,所以④處Child5無法重寫doStuff2(),因此也就不會有後綁定的多態。亦即:父類中final的方法不支援後綁定的多態。

 

 

 

 

 

例子二:

 

class Base5 {

       protected void doStuff1() {

              System.out.println("Base-doStuff1");

       }

       private void doStuff2() {

              System.out.println("Base-doStuff2");

       }

}

 

class Child5 extends Base5 {

       protected void doStuff1() {

              System.out.println("Child-doStuff1");

       }

       protected void doStuff2() {

              System.out.println("Child-doStuff2");

       }

      

       public static void main(String[] args) {

              Base5 c = new Child5();

              c.doStuff1();

              c.doStuff2();

       }

}

 

 

編譯結果如下:

 

D:/JavaEx/scjp/tst/tst18.java:21: doStuff2() has private access in Base5

              c.doStuff2();

                 ^

1 error

 

 因為是私人成員,所以c.doStuff2()會產生錯誤,但更重要的是private就相當於final,父類中的final方法不支援後綁定,則private也是如此。亦即:父類中private的方法不支援後綁定的多態。

只有一步之遙

離解答問題只有一步之遙,還得補充一個基本常識。類的成員方法不論是否接受參數,它其實都隱含地接受了一個參數,即this。

 

何謂this?由《Thinking in Java(3rd Edition)》中:this是對當前對象的一個引用。

 

 

 

回到最初的問題:

 

class Parent {       

        private void method1() {

                System.out.println("Parent's method1()");

        }

        public void method2() {

                System.out.println("Parent's method2()");

                method1();           // ⑤

        }

}

class Child extends Parent {

        public void method1() {

                System.out.println("Child's method1()");

        }

        public static void main(String args[]){

                Parent p = new Child();

                p.method2();

        }

}

 由上一段補充的知識可知⑤處實際上是:

this.method1();

根據例子一和二可知,父類中private的方法不支援後綁定多態,因此它嚴格按照引用的類型來調用對應的方法,因此它調用Parent的method1()。

當把Parent的method1()前的private換成public/protected/friendly(預設),則後綁定將順利完成,自動調用Child的method1()。

 總結

父類中final的方法在子類中無法被重寫,因此不會有後綁定多態的問題。

 父類中private的方法類似於final,雖然可以被重新定義,但不是重寫。

 當出現父類中含有private的方法的後綁定多態問題時,非private方法依然可以根據後綁定對象的實際情況,即時調用對應的方法;而private的方法,不支援此特性,它只根據調用它的參考型別來確定需要調用的方法。

原文地址:http://lslling.blogchina.com/1717345.html

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.