Java 重載、重寫和隱藏的區別
Java 重載、重寫和隱藏的區別
一、重載(Overload)
註意:為了正確的區分重載和重寫,請各位務必記清重載(Overload)和重寫(Override)的英文。
(1)重載定義:表示兩個或多個方法的名字相同,但方法的參數不同。方法參數不同有兩層含義:A、參數的個數不同;B、參數的類型不同。
[java] view plain copy
- public void run(String name, int count)
- {
- System.out.println(count + " " + name + " " + "are running.");
- }
- public
- {
- System.out.println(count + " " + name + " " + "are running.");
- }
請思考以上兩個方法是否構成了重載?
(2)重載發生的時機:重載是發生在同一個類內部的兩個或多個方法之間。
(3)方法的返回類型對重載沒有任何影響!即,對於方法名字和參數都相同的兩個方法,如果他們的返回類型不同,這種語法格式是錯誤的,大家可以試一試。那麽,也就是說,只要是重載返回類型一定相同。否則為兩個不同的方法。如下代碼,這是兩個不同的方法。
[java] view plain copy
- public void run()
- {
- System.out.println("dog is running");
- }
- public int run(String name, int count)
- {
- System.out.println(count + " " + name + " " + "are running.");
- return 1;
- }
(3)構造方法之間的重載:一個類中有多個構造方法,那麽它們一定是重載的。
(4)重載方法之間的調用:對於普通方法的重載,重載的方法之間是可以直接調用的,如下代碼一。
但是對於重載的構造方法之間的調用,需要使用
[java] view plain copy
- public int run(String name, int count)
- {
- System.out.println(count + " " + name + " " + "are running.");
- return 1;
- }
- public void run(int count, String name)
- {
- run(name , count);
- System.out.println(count + " " + name + " " + "are running.");
- }
[java] view plain copy
- public Dog()
- {
- this("金巴");
- System.out.println("你好世界,我是一條狗!");
- }
- public Dog(String name)
- {
- System.out.println("你好世界," + "我是一條" + name + "狗!");
- }
二、重寫(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
- class Animal
- {
- public void run()
- {
- System.out.println("animal is running");
- }
- }
- class Dog extends Animal
- {
- //override
- public void run()
- {
- System.out.println("dog is running");
- super.run();
- }
- }
三、隱藏(Hide)
(1)提到隱藏,就不得不提到一個關鍵字--static,static是靜態的意思,具體用法意義,各位可以去查相關的資料。這裏我想說的,static方法在繼承中的特殊性!
(1)子類不能重寫(Overriding)父類的靜態方法,只能隱藏(Hiding)父類的靜態方法。
(2)什麽叫隱藏父類的靜態方法呢?就是說父類的靜態方法和子類的靜態方法是同時存在的,具體調用的是哪個方法,是要看調用的方法的引用是什麽類型的引用,如果是父類型的引用,調用的就是父類的靜態方法,如果是子類型的引用,調用的就是子類的靜態方法。【這裏面有些多態(Polymorphism)的知識,不懂的可以問我哈!】具體區別我們可以看一個例子,這個例子來自官方文檔。
[java] view plain copy
- public class Animal
- {
- public static void testClassMethod()
- {
- System.out.println("The class" + " method in Animal.");
- }
- public void testInstanceMethod()
- {
- System.out.println("The instance " + " method in Animal.");
- }
- }
The second class, a subclass of Animal, is called Cat:
[java] view plain copy
- public class Cat extends Animal
- {
- public static void testClassMethod()
- {
- System.out.println("The class method" + " in Cat.");
- }
- public void testInstanceMethod()
- {
- System.out.println("The instance method" + " in Cat.");
- }
- public static void main(String[] args)
- {
- Cat myCat = new Cat();
- Animal myAnimal = myCat;
- Animal.testClassMethod();
- myAnimal.testInstanceMethod();
- }
- }
隱藏:父類和子類擁有相同名字的屬性或者方法時,父類的同名的屬性或者方法形式上不見了,實際是還是存在的。
隱藏現象發生在子類和父類之間,隱藏是針對父類中成員變量和靜態方法而言。
當子類聲明與父類中成員變量具有相同的變量名的變量時,則實現了對父類中成員變量的隱藏;
當子類聲明了與父類中的靜態成員方法具有相同的方法名,參數列表和相同的返回值時,則實現了對父類中靜態方法的隱藏。
註意:當發生隱藏的時候,聲明類型是什麽類,就調用對應類的屬性或者方法,而不會發生動態綁定
方法隱藏只有一種形式,就是父類和子類存在相同的靜態方法
屬性只能被隱藏,不能被覆蓋
子類實例變量/靜態變量可以隱藏父類的實例/靜態變量,總結為變量可以交叉隱藏
隱藏和覆蓋的區別:
被隱藏的屬性,在子類被強制轉換成父類後,訪問的是父類中的屬性
被覆蓋的方法,在子類被強制轉換成父類後,調用的還是子類自身的方法
因為覆蓋是動態綁定,是受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;
- public class SuperClass {
- public static int i = 1;
- public int j = 2;
- public final int k = 3;
- public static void method1() {
- System.out.println("SuperClass Method1");
- }
- public void method2() {
- System.out.println("SuperClass Method2");
- }
- public final void method3() {
- System.out.println("SuperClass Method3");
- }
- }
Java 重載、重寫和隱藏的區別