方法

北方的尘中客發表於2024-09-27

方法

一、概述

方法,也稱函式,如果想要重複一段或者多段程式碼塊的使用,可以將這些程式碼封裝成一個方法,方法具體表現為某種行為,使用方法可以提高程式碼的複用性。

二、方法的種類

1.構造方法

構造方法的概念

1.構造器用於建立物件,方法名必須與類名相同,不需要定義返回值型別。

2.構造方法分為有參構造和無參構造,有參構造帶引數,無參構造不帶引數。

3.一個類預設會自帶一個無參構造方法,如果手動定義了有參構造,則會覆蓋預設的無參構造。

Text1 t1 = new Text1();//引用無參建構函式建立物件
Text1 t2 = new Text1("張三",18);//引用有參建構函式建立物件

2.靜態方法

2.1. 關鍵字static修飾的方法稱為靜態方法,也叫類方法,靜態方法不屬於物件,而是屬於類,隨著類的載入而載入,優先於構造方法執行。
2.2.靜態方法可以直接使用類名.方法直接呼叫,如果靜態方法位於本類中可以直接省略類名直接呼叫
2.3. 在靜態方法中,可以訪問靜態方法,可以引用類變數(被static修飾的變數),不能訪問非靜態方法與變數,不能使用super和this關鍵字

3.非靜態方法

3.1是不含有static關鍵字修飾的普通方法,又稱為例項方法,成員方法。屬於物件的,不屬於類的。(成員屬性,成員方法是屬於物件的,必須透過new關鍵字建立物件後,再透過物件呼叫)。
3.2在非靜態方法中,即可以呼叫非靜態方法,也可以呼叫靜態方法,可以引用類變數和成員變數,可以使用關鍵字super和this

public class Text3 {
	
	int age = 18;//成員變數
	static String name = "迪麗熱巴";//類變數
	
	public static void main(String[] args) {
		Text3 t1 =  new Text3();
		method();//本類中呼叫靜態方法,直接省略類名
		t1.method1();//呼叫成員方法
	}
	
	//靜態方法
	static void method() {
		System.out.println("靜態方法");
		//訪問屬性
		System.out.println(name);
		//System.out.println(age);//報錯,靜態不能訪問非靜態
		//t1.method();//報錯
	}
	
	//非靜態方法,也叫成員方法
	void method1() {
		System.out.println("非靜態方法1");
		method();//既可以呼叫靜態方法
		new Text3().method2();//又可以呼叫非靜態方法
		
		System.out.println(name);//既可以訪問靜態屬性
		System.out.println(age);//又可以訪問非靜態屬性
	}
	void method2() {
		System.out.println("非靜態方法2");
	}
}

這段程式碼定義了一個名為 Text3 的類,並在其中展示了靜態方法和非靜態方法的使用。以下是程式碼的詳細解釋:

  1. 成員變數和類變數

    • int age = 18; 是一個非靜態成員變數(例項變數),每個 Text3 類的例項都有自己的 age 值。
    • static String name = "迪麗熱巴"; 是一個靜態類變數(類變數),所有 Text3 類的例項共享這個 name 變數。
  2. main 方法

    • 建立了 Text3 類的一個例項 t1
    • 呼叫靜態方法 method(),不需要物件例項,可以直接透過類名呼叫。
    • 呼叫非靜態方法 method1(),需要透過物件例項 t1 呼叫。
  3. 靜態方法 method

    • 靜態方法可以被類名直接呼叫,不需要建立類的例項。
    • 在靜態方法中,可以訪問靜態變數,如 name,但不能直接訪問非靜態變數,如 age
    • 靜態方法不能直接訪問非靜態方法,因為非靜態方法依賴於類的例項。
  4. 非靜態方法 method1

    • 非靜態方法需要透過物件例項呼叫。
    • 在非靜態方法中,可以訪問靜態變數和非靜態變數,也可以呼叫靜態方法和非靜態方法。
    • method1 方法中呼叫了靜態方法 method 和另一個非靜態方法 method2
  5. 非靜態方法 method2

    • 這個方法簡單地列印出 "非靜態方法2"。

輸出
當執行這段程式碼時,輸出將如下所示:

靜態方法
迪麗熱巴
非靜態方法1
非靜態方法2
迪麗熱巴
18

解釋

  • 首先,呼叫 method(),列印 "靜態方法" 和類變數 name 的值。
  • 然後,呼叫 method1(),列印 "非靜態方法1",接著建立一個新的 Text3 物件並呼叫 method2(),列印 "非靜態方法2"。
  • method1() 中,列印靜態變數 name 和非靜態變數 age 的值。

注意

  • 靜態方法屬於類本身,而非靜態方法屬於類的例項。
  • 靜態方法中不能直接訪問非靜態變數或呼叫非靜態方法,因為它們需要一個物件例項。
  • 非靜態方法可以訪問類的任何變數和呼叫任何方法,無論是靜態的還是非靜態的。

4.抽象方法

關鍵字abstract修飾的方法稱為抽象方法,抽象方法必須定義在抽象類(abstract修飾的類稱為抽象類)中,抽象類中既有抽象方法,也有非抽象方法,但是抽象方法必須定義在抽象類中,並且抽象方法沒有方法體

public class Text3 {
	public static void main(String[] args) {
		Cat cat = new Cat();
		cat.cry();
	    }
	}

	// 定義一個抽象類
	abstract class Animal {
	    String name;
	    int age;
	    // 抽象方法
	    public abstract void cry(); // 不確定動物怎麼叫的。定義成抽象方法,來解決父類方法的不確定性。
	    							//抽象方法在父類中不能實現,所以沒有方法體。但在後續在繼承時,要具體實現此方法。
	}
	// 抽象類可以被繼承
	// 當繼承的父類是抽象類時,需要將抽象類中的所有抽象方法全部實現。
	class Cat extends Animal {
	    // 實現父類的cry抽象方法
	    public void cry() {
	        System.out.println("貓叫:苗苗苗");
	    }
	}

注:靜態方法和非靜態方法的區別(生命週期不同)

靜態方法的生命週期跟相應的類一樣長,靜態方法和靜態變數會隨著類的定義而被分配和裝載入記憶體中。一直到執行緒結束,靜態屬性和方法才會被銷燬。(也就是靜態方法屬於類)
非靜態方法的生命週期和類的例項化物件一樣長,只有當類例項化了一個物件,非靜態方法才會被建立,而當這個物件被銷燬時,非靜態方法也馬上被銷燬。(也就是非靜態方法屬於物件)

三、下面是構造方法與普通方法的一些關鍵區別:

構造方法的特點:

  • 名稱:構造方法的名稱必須與類名完全相同,而普通方法可以自由命名。
  • 返回型別:構造方法沒有返回型別宣告,甚至沒有void型別,而普通方法可以有不同的返回型別,包括void
  • 呼叫方式:構造方法是在建立物件時自動呼叫的,透過new關鍵字來建立物件,而普通方法需要透過已建立的物件或類名(如果是靜態方法)顯式呼叫。
  • 初始化職責:構造方法主要用於初始化物件的狀態,如分配記憶體、設定預設值等。普通方法則用於實現類的具體功能,執行特定的任務。
  • 過載:構造方法可以被過載,即一個類可以定義多個構造方法,透過不同的引數列表來實現構造方法的過載。
  • 修飾符:構造方法不能被staticfinalsynchronizedabstractnative修飾,而普通方法可以使用這些修飾符。
  • 預設構造方法:如果一個類沒有顯式定義構造方法,Java編譯器會自動為該類提供一個無參構造方法。但如果一個類已經定義了構造方法,則Java編譯器不會為其再生成預設的無參構造方法。

普通方法的特點:

  • 名稱:普通方法的名稱可以自由定義,只要符合程式語言的規則。
  • 返回型別:普通方法可以有各種返回型別,包括void(表示沒有返回值)。
  • 主要用途:普通方法用於執行特定的功能或計算,可以修改物件狀態或者返回計算結果。
  • 呼叫方式:普通方法需要透過已建立的物件或類名(如果是靜態方法)顯式呼叫。

示例

假設有一個名為Person的類,下面是一個構造方法和普通方法的例子:

public class Person {
    private String name;
    private int age;

    // 構造方法
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // 普通方法
    public void introduce() {
        System.out.println("Hello, my name is " + name + " and I am " + age + " years old.");
    }
}

在這個例子中,Person類有兩個屬性:nameage。構造方法接受這兩個引數,並將它們賦值給相應的成員變數。introduce方法是一個普通方法,它輸出一個字串介紹這個人的資訊。

結論

構造方法與普通方法的主要區別在於它們的用途和呼叫方式。構造方法專注於物件的初始化,並在物件建立時自動呼叫,而普通方法則用於執行業務邏輯,並需要顯式呼叫。理解這些區別有助於更有效地編寫和維護物件導向的程式。

四、構造方法和普通方法分別可以呼叫哪種方法

構造方法和普通方法在Java中都可以呼叫其他的方法,但它們之間的呼叫方式有一些限制和規範。

構造方法可以呼叫的方法:

  1. 其他構造方法:構造方法內部可以呼叫同一個類中的其他構造方法,這種呼叫必須發生在構造方法的第一行,並且使用this關鍵字加上引數列表來指定要呼叫的構造方法。這種呼叫方式通常用於程式碼複用。

    public class Example {
        public Example() {
            // 呼叫帶有引數的構造方法
            this("default");
        }
    
        public Example(String value) {
            // 初始化邏輯
        }
    }
    
  2. 普通方法:構造方法也可以呼叫類中的任何普通方法,但需要注意的是,由於構造方法在物件建立時呼叫,因此在呼叫普通方法時,物件的狀態可能尚未完全初始化。

    public class Example {
        private int value;
    
        public Example() {
            setValue(10);
            printValue();
        }
    
        private void setValue(int newValue) {
            value = newValue;
        }
    
        public void printValue() {
            System.out.println(value);
        }
    }
    

普通方法可以呼叫的方法:

  1. 其他普通方法:普通方法可以呼叫類內的其他普通方法,這種方式非常靈活,可以根據需要在任何地方呼叫。

    public class Example {
        public void methodA() {
            methodB();
        }
    
        private void methodB() {
            // 實現細節
        }
    }
    
  2. 構造方法:普通方法不能直接呼叫構造方法,因為構造方法是在物件建立時由JVM自動呼叫的,而普通方法是在物件建立之後才呼叫的。

    // 錯誤示範:
    public class Example {
        public void someMethod() {
            new Example(); // 這實際上是在建立一個新的物件
        }
    }
    

特殊情況:

  • 靜態方法:不論是構造方法還是普通方法,都可以呼叫類中的靜態方法,因為靜態方法並不依賴於任何特定物件的存在。

    public class Example {
        public static void staticMethod() {
            // 實現細節
        }
    
        public Example() {
            staticMethod();
        }
    
        public void instanceMethod() {
            staticMethod();
        }
    }
    

總之,構造方法主要用於初始化物件,而普通方法則用於實現物件的行為。構造方法可以呼叫其他構造方法或普通方法來輔助初始化過程,而普通方法則主要用於實現業務邏輯,並且可以呼叫類中的其他普通方法或靜態方法。需要注意的是,構造方法不應直接被普通方法呼叫,因為構造方法是在物件建立時由系統自動呼叫的。

五、方法的宣告

1.組成

訪問許可權符 返回值  方法名(引數列表){
	方法體
}
public viod method(){
	System.out.println(“Hello World!!!”);
}

2.訪問許可權符

表示該方法被訪問的許可權,主要有以下幾種

public

(1)定義:public是公共的,被public所修飾的成員可以在任何類中都能被訪問到。
(2)作用域:public能來修飾類,在一個java原始檔中只能有一個類被宣告為public,而且一旦有一個類為public,那這個java原始檔的檔名就必須要和這個被public所修飾的類的類名相同,否則編譯不能透過。public用來修飾類中成員(變數和方法),被public所修飾的成員可以在任何類中都能被訪問到。透過操作該類的物件能隨意訪問public成員。public在類的繼承上的體現,被public所修飾的成員能被所有的子類繼承下來。

protected

(1)定義:protected是受保護的,受到該類所在的包所保護。
(2)作用域:被protected所修飾的成員會被位於同一package中的所有類訪問到。同時,被protected所修飾的成員也能被該類的所有子類繼承下來。(注意:這裡是指同一個package或者不同的package中的子類都能訪問)

default

(1)定義:default是預設,預設的,即在成員的前面不寫任何的訪問修飾符的時候,預設就是友好的。所謂友好的,是對同一package的類友好。
(2)作用域:同一package中的所有類都能訪問。被friendly所修飾的成員只能被該類所在同一個package中的子類所繼承下來。(也就是說只有在同一個package中的子類才能訪問到父類中friendly修飾的成員)

private

(1)定義:private是私有的,即只能在當前類中被訪問到,它的作用域最小。
(2)作用域:private可以修飾資料成員,構造方法,方法成員,不能修飾類(此處指外部類,不考慮內部類)。被private修飾的成員,只能在定義它們的類中使用,在其他類中不能呼叫。

以下是四種主要的訪問修飾符及其對應的訪問範圍:

訪問修飾符 描述 示例程式碼
public 最寬鬆的訪問級別,允許任何類訪問該成員。 public class MyClass { public void method() {} }
protected 成員可以被同一個包內的類訪問,也可以被不同包中的子類訪問。 protected class MyClass { protected void method() {} }
預設(無修飾符) 成員僅能被同一個包內的類訪問,這種許可權也稱為包級許可權。 class MyClass { void method() {} }
private 最嚴格的訪問級別,成員只能被其所在的類訪問。 private class MyClass { private void method() {} }
訪問修飾符 同一類中 同一包 不同包中的非子類 不同包中的子類 同包的子類
public
protected
預設
private

這裡,“同一檔案”意味著成員可以被定義在同一原始檔中的其他類訪問;“同一包”指的是成員可以被位於同一個包中的類訪問;“不同包中的非子類”是指那些不在同一包內的類,且不是繼承關係;而“不同包中的子類”則是指位於不同包內的類,但是子類繼承了擁有成員的那個類。

請注意,這裡提到的“同一檔案”實際上並不是標準的術語,但它有助於理解在同一個原始檔中定義的內部類或巢狀類如何訪問外部類的成員。對於private成員來說,即使在同一檔案中,也只有包含該成員的類能夠訪問到它。

3.返回值:

表示方法(函式)要返回的資料型別,int ,double,String等等·,void表示無返回值

4.方法名:

方法的名稱,避免使用到java關鍵字,並且首字母小寫,命名時使用駝峰命名法
駱駝式命名法(Camel-Case)又稱駝峰式命名法,是電腦程式編寫時的一套命名規則(慣例)。正如它的名稱CamelCase所表示的那樣,是指混合使用大小寫字母來構成變數和函式的名字。程式設計師們為了自己的程式碼能更容易的在同行之間交流,所以多采取統一的可讀性比較好的命名方式。

5.引數列表:

方法宣告時可以定義引數列表,呼叫時需要傳入實參

5.1 形參

也叫形式引數,方法宣告時候的引數稱為形參,如add(int a)

5.2 實參

也叫實際引數,方法呼叫時傳入的引數,如add(1)

public class Text {
public static void main(String[] args) {
	method("字元引數");//括號中為實參
}
private static void method(String str) {//括號中為形參
	System.out.println(str);//將傳入的引數列印輸出
}
}

5.3 可變引數

1.當引數的個數不定時,可以使用可變引數
2.可變引數的寫法:int…a 前面為引數型別,中間加三個點,後面為引數名
3.使用規則:

  • 可變引數只能位於引數列表的最後一個

  • 可變引數有且只有一個

4.可變引數的原理為陣列,傳入引數時,根據傳入的引數自動生成匹配的陣列型別,陣列長度等於傳入的引數個數,陣列元素為傳入的實參

public class Text2 {
	public static void main(String[] args) {
		int sum = addSum(1,2,3,4,5,6,7,8,9);
		System.out.println(sum);
	}

private static int addSum(int ...a) {
	int add = 0;
	//將陣列元素(即傳入的引數)求和
	for (int i = 0; i < a.length; i++) {
		add += a[i];
	}
	return add;
}

}

六、方法的宣告與呼叫

public class Text3 {
	//定義4種方法
	private static void method1() {
		System.out.println("無參無返回值的方法");
	}
	private static int method2() {
		System.out.println("無參有返回值的方法");
		return 1;
	}

	private static int method3(String str) {
		System.out.println("有參有返回值的方法");
		return 1;
	}

	private static void method4(String str) {
		System.out.println("有參無返回值的方法");
	}
	
	public static void main(String[] args) {
		//呼叫方法
		method1();
		method2();
		method3("我");
		method4("你");	
	}
}

物件的建立與構造方法的應用

1.物件是透過建構函式建立的,預設透過呼叫無參構造方法建立。

2.在Java中,建立物件有兩種方式:先建立物件再賦值和邊建立邊賦值,後者透過有參構造方法實現。

3.有參構造方法可以透過形參接收外部傳入的值,並賦給物件的屬性。 4.在構造方法中使用this關鍵字可以引用當前物件的屬性或呼叫其他構造方法。

this關鍵字的用法

1.this關鍵字用於指代當前類的例項化物件,可以用於訪問物件的屬性和方法。

2.在構造方法中,this可以用來呼叫其他構造方法,但只能在構造方法中使用。

3.this還可以用於區分成員變數和形式引數,避免命名衝突。

建構函式中的錯誤寫法及解決方式

1.在建構函式中直接呼叫無參建構函式會導致死迴圈,引發記憶體溢位錯誤。

2.正確的做法是根據需要選擇呼叫有參或無參建構函式,避免無限遞迴。

七、JVM記憶體結構劃分

在JVM(Java Virtual Machine)的記憶體結構中,堆(Heap)和棧(Stack,通常是指虛擬機器棧VM Stack和本地方法棧Native Method Stack的統稱,但在這裡我們主要討論虛擬機器棧)是兩個非常重要的區域,它們在功能、儲存內容、生命週期以及管理方式上都有顯著的不同。

堆(Heap)

  • 描述:堆是JVM中用於儲存物件例項和陣列的記憶體區域。它是JVM管理的最大一塊記憶體區域,也是垃圾收集器管理的主要區域。

  • 特性:

    • 堆是執行緒共享的,多個執行緒可以訪問同一個堆中的物件。
    • 堆的大小在JVM啟動時確定,並可以透過JVM啟動引數(如-Xms和-Xmx)進行調整。
    • 堆被劃分為新生代(Young Generation)和老年代(Old Generation),新生代又被進一步劃分為Eden區、From Survivor區(S0)和To Survivor區(S1)。
    • 堆記憶體中的物件由垃圾收集器進行回收,當堆記憶體不足時,會觸發垃圾收集。

棧(Stack,主要指虛擬機器棧VM Stack)

  • 描述:棧是每個執行緒私有的記憶體區域,用於儲存區域性變數表、運算元棧、動態連結、方法出口等資訊。當一個方法被呼叫時,JVM會在這個執行緒的棧中建立一個棧幀(Stack Frame)來儲存這個方法呼叫的相關資訊。

  • 特性:

    • 棧是執行緒私有的,每個執行緒都有自己獨立的棧空間。
    • 棧的大小在JVM啟動時確定,但棧的大小限制通常不是由JVM直接設定的,而是由作業系統和JVM的具體實現決定的。
    • 棧是後進先出(LIFO)的資料結構,當一個方法被呼叫時,它的棧幀被壓入棧頂;當方法執行完成後,它的棧幀被彈出棧頂。
    • 如果棧的深度超過了JVM所允許的最大深度,就會丟擲StackOverflowError異常;如果棧在嘗試擴充套件時無法申請到足夠的記憶體空間,就會丟擲OutOfMemoryError異常。

堆和棧在JVM記憶體結構中扮演著不同的角色:

  • 堆用於儲存物件例項和陣列,是垃圾收集器管理的主要區域,是執行緒共享的。
  • 棧用於儲存區域性變數表、運算元棧、動態連結、方法出口等資訊,是執行緒私有的,用於支援方法的呼叫和執行。

理解堆和棧的區別對於深入理解JVM的記憶體管理和最佳化Java程式的效能至關重要。

八、方法的過載

方法過載

方法過載指的是在同一個類中定義多個具有相同名稱但引數列表不同的方法。這裡的“引數列表”指的是方法引數的個數、型別以及引數的順序。方法的返回型別和訪問修飾符並不能作為判斷方法是否過載的標準 。

方法過載的條件

要構成方法過載,必須滿足以下條件:

  1. 方法名相同。
  2. 引數列表不同,即引數的個數、型別或順序至少有一項不同。
  3. 方法的返回型別可以相同也可以不同,但這不是判斷過載的關鍵條件 。

方法過載的目的

方法過載的目的在於提高程式碼的可讀性和可用性,同時也增強了程式碼的靈活性。透過使用相同的方法名,可以使得程式碼更加清晰易懂,並且易於維護 。

方法過載的示例

以下是幾個方法過載的示例:

public class MathUtil {

    // 過載方法disp,分別接受char和int型別的引數
    public static void disp(char ch) {
        System.out.println("字元:" + ch);
    }

    public static void disp(int num) {
        System.out.println("整數:" + num);
    }

    // 過載方法add,處理不同型別的加法運算
    public static int add(int a, int b) {
        return a + b;
    }

    public static double add(double a, double b) {
        return a + b;
    }

    public static void main(String[] args) {
        MathUtil.disp('A'); // 呼叫disp(char ch)
        MathUtil.disp(1);   // 呼叫disp(int num)

        int sumInt = MathUtil.add(2, 3); // 呼叫add(int a, int b)
        double sumDouble = MathUtil.add(2.5, 3.5); // 呼叫add(double a, double b)
        
        System.out.println("整數相加的結果是:" + sumInt);
        System.out.println("浮點數相加的結果是:" + sumDouble);
    }
}

在這個示例中,dispadd 方法都進行了過載,透過不同的引數型別或個數實現了不同的功能。當呼叫這些方法時,Java編譯器會根據傳遞的實際引數來選擇合適的方法執行 。

方法過載的注意事項

雖然方法過載提供了便利,但也需要注意以下幾點:

  • 方法的返回型別不能作為過載的依據。
  • 僅僅是返回型別不同不足以構成方法的過載。
  • 引數列表的差異決定了方法的過載。

結論

方法過載是Java語言中一種重要的特性,它允許程式設計師在同一個類中定義多個同名但引數列表不同的方法,從而提高程式碼的可讀性和靈活性。正確使用方法過載可以幫助編寫更清晰、更易於維護的程式碼。

九、方法重寫

方法重寫的基本概念

  • 定義:當子類中的方法與父類中的某一方法具有相同的方法名、返回型別和參數列時,我們說子類中的方法覆蓋(overriding)了父類中的方法。
  • 目標:子類可以改變繼承自父類的方法的行為,以適應子類特有的需求。
  • 好處:提高了程式碼的靈活性和可擴充套件性,同時也支援了多型性。

方法重寫的規則

  1. 引數列表必須完全與被重寫方法的相同;
  2. 返回型別必須完全與被重寫方法的返回型別相同;
  3. 訪問許可權不能比父類中被重寫的方法的訪問許可權更低;
  4. 宣告為final的方法不能被重寫;
  5. 宣告為static的方法不能被重寫,但是能夠被再次宣告;
  6. 構造方法不能被重寫;
  7. 子類和父類在同一個包中,那麼子類可以重寫父類所有除了宣告為private和final的方法;
  8. 如果不能繼承一個方法,則不能重寫這個方;
  9. 子類和父類不在同一個包中,那麼子類只能夠重寫父類的宣告為public和protected的非final方法;
  10. 重寫的方法能夠丟擲任何非強制異常,無論被重寫的方法是否丟擲異常。但是,重寫的方法不能丟擲新的強制性異常,或者比被重 寫方法宣告的更廣泛的強制性異常,反之則可以。

注意事項

  • 私有方法:私有方法不能被重寫(父類私有成員子類是不能繼承的)。
  • 靜態方法:父類中的靜態方法不能被重寫,如果子類中有相同的方法,它並不是重寫了父類的方法,而是將父類同名的方法隱藏了起來。
  • 使用@Override註解:建議在子類中重寫父類的方法時加上@Override註解,這可以提高程式碼的可讀性,並且可以在編譯階段檢查重寫是否正確。

示例程式碼

以下是一個簡單的示例,展示了方法重寫的基本用法:

class Animal {
    public void eat() {
        System.out.println("Animal is eating");
    }
}

class Dog extends Animal {
    // 重寫父類的方法
    @Override
    public void eat() {
        System.out.println("Dog is eating");
    }

    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.eat();  // 輸出 "Dog is eating"
        
        // 多型性演示
        Animal myDog = new Dog();
        myDog.eat();  // 輸出 "Dog is eating"
    }
}

在這個例子中,Dog類繼承了Animal類,並重寫了eat()方法。當我們透過Dog型別的引用呼叫eat()方法時,輸出的是"Dog is eating",這體現了方法重寫的多型性特徵。

方法重寫是Java中實現多型的一種方式,透過這種方法,可以使程式更加靈活,並且能夠有效地擴充套件父類的功能,而不改變父類的實現。

注、方法重寫與方法過載區別

  • 方法過載:在同一個類中,允許存在一個以上的同名方法,只要它們的引數個數或者引數型別不同即可。
  • 方法重寫:子類可以有一個與父類簽名完全相同的方法,即子類可以重寫父類的方法。

十、在Java中,什麼時候用過載,什麼時候用重寫?

(1)過載是多型的集中體現,在類中,要以統一的方式處理不同型別資料的時候,可以用過載。
(2)重寫的使用是建立在繼承關係上的,子類在繼承父類的基礎上,增加新的功能,可以用重寫。
(3)簡單總結:
1.過載是多樣性,重寫是增強劑;
2.目的是提高程式的多樣性和健壯性,以適配不同場景使用時,使用過載進行擴充套件;
3.目的是在不修改原方法及原始碼的基礎上對方法進行擴充套件或增強時,使用重寫;

相關文章