1. 程式人生 > >Java 重載、重寫和隱藏的區別

Java 重載、重寫和隱藏的區別

目標 phi 為什麽不能 int title ide 修改 cati 修飾

Java 重載、重寫和隱藏的區別

一、重載(Overload)

註意:為了正確的區分重載和重寫,請各位務必記清重載(Overload)和重寫(Override)的英文。

1)重載定義:表示兩個或多個方法的名字相同,但方法的參數不同。方法參數不同有兩層含義:A、參數的個數不同;B、參數的類型不同。

[java] view plain copy

  1. public void run(String name, int count)
  2. {
  3. System.out.println(count + " " + name + " " + "are running.");
  4. }
  5. public
    void run(int count, String name)
  6. {
  7. System.out.println(count + " " + name + " " + "are running.");
  8. }

請思考以上兩個方法是否構成了重載?

2)重載發生的時機:重載是發生在同一個類內部的兩個或多個方法之間。

3)方法的返回類型對重載沒有任何影響!即,對於方法名字和參數都相同的兩個方法,如果他們的返回類型不同,這種語法格式是錯誤的,大家可以試一試。那麽,也就是說,只要是重載返回類型一定相同。否則為兩個不同的方法。如下代碼,這是兩個不同的方法。

[java] view plain copy

  1. public void run()
  2. {
  3. System.out.println("dog is running");
  4. }
  5. public int run(String name, int count)
  6. {
  7. System.out.println(count + " " + name + " " + "are running.");
  8. return 1;
  9. }

3)構造方法之間的重載:一個類中有多個構造方法,那麽它們一定是重載的。

4)重載方法之間的調用:對於普通方法的重載,重載的方法之間是可以直接調用的,如下代碼一。

但是對於重載的構造方法之間的調用,需要使用

this()關鍵字。A、this()括號中參數表示目標構造方法所接收的參數;B、對this()的調用必須是構造方法的第一條語句。如下代碼二。

[java] view plain copy

  1. public int run(String name, int count)
  2. {
  3. System.out.println(count + " " + name + " " + "are running.");
  4. return 1;
  5. }
  6. public void run(int count, String name)
  7. {
  8. run(name , count);
  9. System.out.println(count + " " + name + " " + "are running.");
  10. }

[java] view plain copy

  1. public Dog()
  2. {
  3. this("金巴");
  4. System.out.println("你好世界,我是一條狗!");
  5. }
  6. public Dog(String name)
  7. {
  8. System.out.println("你好世界," + "我是一條" + name + "狗!");
  9. }

二、重寫(Override)

1)重寫定義:子類與父類的方法的返回類型一樣,方法名稱一樣,參數一樣,這樣我們就說子類與父類的方法構成了重寫關系。

補充:在重寫中,我們一直沒提到權限的問題(public、protected、private),使用private修飾的方法是不能夠進行重寫的,也不能夠被繼承,所以private和多態扯不上關系。在同一個包下,構成重寫關系,父類和子類的方法,權限可以是public和public、protected和protected、protected和public,但不可能是public和protected,即權限可以擴大但不可縮小。

2)重寫發生的時機:重寫發生在父類與子類之間。

3)構造方法時不能重寫的,如果您理解是構造方法的作用,就知道構造方法為什麽不能重寫。

4)在重寫時,子類重寫的方法調用父類被重寫的方法時,可以使用super.父類方法的方式調用,其中此語句不必放在第一行。如下代碼所示:

[java] view plain copy

[java] view plain copy

  1. class Animal
  2. {
  3. public void run()
  4. {
  5. System.out.println("animal is running");
  6. }
  7. }
  8. class Dog extends Animal
  9. {
  10. //override
  11. public void run()
  12. {
  13. System.out.println("dog is running");
  14. super.run();
  15. }
  16. }

三、隱藏(Hide)
1)提到隱藏,就不得不提到一個關鍵字--static,static是靜態的意思,具體用法意義,各位可以去查相關的資料。這裏我想說的,static方法在繼承中的特殊性!
1)子類不能重寫(Overriding)父類的靜態方法,只能隱藏(Hiding)父類的靜態方法。

2)什麽叫隱藏父類的靜態方法呢?就是說父類的靜態方法和子類的靜態方法是同時存在的,具體調用的是哪個方法,是要看調用的方法的引用是什麽類型的引用,如果是父類型的引用,調用的就是父類的靜態方法,如果是子類型的引用,調用的就是子類的靜態方法。【這裏面有些多態(Polymorphism)的知識,不懂的可以問我哈!】具體區別我們可以看一個例子,這個例子來自官方文檔。

[java] view plain copy

  1. public class Animal
  2. {
  3. public static void testClassMethod()
  4. {
  5. System.out.println("The class" + " method in Animal.");
  6. }
  7. public void testInstanceMethod()
  8. {
  9. System.out.println("The instance " + " method in Animal.");
  10. }
  11. }

The second class, a subclass of Animal, is called Cat:

[java] view plain copy

  1. public class Cat extends Animal
  2. {
  3. public static void testClassMethod()
  4. {
  5. System.out.println("The class method" + " in Cat.");
  6. }
  7. public void testInstanceMethod()
  8. {
  9. System.out.println("The instance method" + " in Cat.");
  10. }
  11. public static void main(String[] args)
  12. {
  13. Cat myCat = new Cat();
  14. Animal myAnimal = myCat;
  15. Animal.testClassMethod();
  16. myAnimal.testInstanceMethod();
  17. }
  18. }

隱藏:父類和子類擁有相同名字的屬性或者方法時,父類的同名的屬性或者方法形式上不見了,實際是還是存在的。

隱藏現象發生在子類和父類之間,隱藏是針對父類中成員變量和靜態方法而言。

當子類聲明與父類中成員變量具有相同的變量名的變量時,則實現了對父類中成員變量的隱藏;

當子類聲明了與父類中的靜態成員方法具有相同的方法名,參數列表和相同的返回值時,則實現了對父類中靜態方法的隱藏。

  註意:當發生隱藏的時候,聲明類型是什麽類,就調用對應類的屬性或者方法,而不會發生動態綁定

     方法隱藏只有一種形式,就是父類和子類存在相同的靜態方法

     屬性只能被隱藏,不能被覆蓋

     子類實例變量/靜態變量可以隱藏父類的實例/靜態變量,總結為變量可以交叉隱藏

隱藏和覆蓋的區別:

  被隱藏的屬性,在子類被強制轉換成父類後,訪問的是父類中的屬性

  被覆蓋的方法,在子類被強制轉換成父類後,調用的還是子類自身的方法

  因為覆蓋是動態綁定,是受RTTI(run time type identification,運行時類型檢查)約束的,隱藏不受RTTI約束,總結為RTTI只針對覆蓋,不針對隱藏

特殊情況:

  1.final修飾的屬性可以被隱藏,但是不能被賦值,即不能用=來賦值,網上說final屬性不能被修改,這個說法不準確,因為對於引用類型的變量用final修飾後,它只是不能被指向其他對象,但是可以改它自身的值,可以用ArrayList測試,final屬性可以在運行的時候進行初始化,但是不能不出現初始化語句

  2.final修飾的方法不能被覆蓋,可以被重載

  3.final修飾的類不能被繼承

  4.private 方法隱式添加了final

實例:

SuperClass類:

   package com.yilong.test.scjp;

  1. public class SuperClass {
  2. public static int i = 1;
  3. public int j = 2;
  4. public final int k = 3;
  5. public static void method1() {
  6. System.out.println("SuperClass Method1");
  7. }
  8. public void method2() {
  9. System.out.println("SuperClass Method2");
  10. }
  11. public final void method3() {
  12. System.out.println("SuperClass Method3");
  13. }
  14. }

Java 重載、重寫和隱藏的區別