- 繼承(包含Object類)
- 何為繼承
- 優點
- 程式碼複用
- 易於維護和擴充套件
- 缺點
- 緊密耦合
- 缺乏靈活性
- 常用的方法
- Object類
- Object類中的常用方法:
- 方法重寫規則
- 方法重寫規則
- 方法重寫與方法過載的區別
- 示例程式碼
super
關鍵字的用法- 示例程式碼
final
關鍵字的用法- 示例程式碼
繼承(包含Object類)
何為繼承
在物件導向程式設計(OOP)中,繼承是一種機制,它允許一個類(稱為子類或派生類)繼承另一個類(稱為父類或基類)的屬性和方法。繼承提供了一種程式碼複用的方式,使得子類可以繼承父類的公共屬性和方法,而不需要重新編寫相同的程式碼。
優點
程式碼複用
透過繼承,可以在現有的類基礎上建立新類,新類自動擁有父類的所有屬性和方法,這樣可以減少程式碼的重複編寫。
易於維護和擴充套件
繼承提供了一種層次結構,使得程式碼更加模組化,易於維護和擴充套件。如果需要修改某個功能,只需要在父類中修改,所有繼承自該父類的子類都會受到影響。
缺點
緊密耦合
繼承建立了類之間的強依賴關係,如果父類發生改變,可能會影響所有繼承自該父類的子類。
缺乏靈活性
繼承是靜態的,一旦定義了繼承關係,就很難改變。這限制了程式碼的靈活性。
常用的方法
在Java中,繼承可以透過關鍵字extends
來實現。下面是一個簡單的示例:
// 父類
class Animal {
void eat() {
System.out.println("動物吃東西");
}
}
// 子類
class Dog extends Animal {
void bark() {
System.out.println("狗叫");
}
}
public class TestInheritance {
public static void main(String[] args) {
Dog myDog = new Dog();
myDog.eat(); // 繼承自Animal類的方法
myDog.bark(); // Dog類特有的方法
}
}
Object類
在Java中,所有的類都隱式地繼承自java.lang.Object
類,這是Java類層次結構的根類。即使在定義類時沒有顯式地指定父類,它也會預設繼承自Object
類。
class MyClass {
// ...
}
public class TestObject {
public static void main(String[] args) {
MyClass myObject = new MyClass();
// 可以使用Object類的方法
myObject.toString();
}
}
Object類中的常用方法:
在Java中,Object
類是所有類的根類,它提供了一些常用的方法,這些方法在很多情況下都非常有用。以下是Object
類的一些常用方法及其簡要說明:
-
equals(Object obj)
:檢查傳遞給此方法的物件是否與該物件相等。預設行為是比較物件的引用,但通常需要根據類的屬性重寫這個方法。 -
hashCode()
:返回該物件的雜湊碼值。支援equals
方法的類通常也應該重寫hashCode
方法,以維護equals
和hashCode
的一致性。 -
toString()
:返回該物件的字串表示。通常需要重寫這個方法以提供更有用的資訊。 -
getClass()
:返回執行時類物件,這個類物件表示該物件的實際類。 -
notify()
和notifyAll()
:喚醒在此物件監視器上等待的單個或所有執行緒。 -
wait()
:導致當前執行緒等待,直到另一個執行緒呼叫此物件的notify()
或notifyAll()
方法。 -
wait(long timeout)
和wait(long timeout, int nanos)
:導致當前執行緒等待,直到另一個執行緒呼叫此物件的notify()
或notifyAll()
方法,或者超過指定的時間。
下面是一個示例,展示瞭如何使用這些方法:
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Person person = (Person) obj;
return age == person.age &&
(name != null ? name.equals(person.name) : person.name == null);
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + age;
return result;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public static void main(String[] args) throws InterruptedException {
Person person1 = new Person("Kimi", 30);
Person person2 = new Person("Kimi", 30);
System.out.println("person1 = " + person1);
System.out.println("person2 = " + person2);
System.out.println("Are person1 and person2 equal? " + person1.equals(person2));
System.out.println("Hash code of person1: " + person1.hashCode());
System.out.println("Hash code of person2: " + person2.hashCode());
// 獲取類物件
System.out.println("Class of person1: " + person1.getClass().getName());
System.out.println("Class of person2: " + person2.getClass().getName());
}
}
在這個例子中,我們重寫了equals
、hashCode
和toString
方法,以便提供更有意義的行為。我們也展示瞭如何獲取物件的類物件,並列印出它的名稱。這個例子沒有展示wait
、notify
和notifyAll
方法的使用,因為它們通常與多執行緒程式設計一起使用,涉及到更復雜的同步機制。
方法重寫規則
方法重寫(Override)是指子類中定義一個與父類中具有相同名稱、引數列表的方法。這是實現多型的一種方式。
方法重寫規則
- 方法名、引數列表和返回型別必須與父類中被重寫的方法相同。
- 訪問許可權不能比父類中被重寫的方法更嚴格。
- 不能重寫父類中宣告為
final
的方法。 - 如果父類中的方法被宣告為
static
,則子類中的方法也必須是static
。
方法重寫與方法過載的區別
- 方法重寫:發生在子類和父類之間,要求方法名、引數列表相同,返回型別相同或相容,訪問許可權相同或更寬鬆。
- 方法過載:發生在同一個類中,要求方法名相同,引數列表不同。
示例程式碼
class Parent {
void show() {
System.out.println("Parent show()");
}
}
class Child extends Parent {
// 方法重寫
void show() {
System.out.println("Child show()");
}
// 方法過載
void show(int num) {
System.out.println("Child show(int num)");
}
}
public class TestOverride {
public static void main(String[] args) {
Child obj = new Child();
obj.show(); // 呼叫重寫的方法
obj.show(10); // 呼叫過載的方法
}
}
super
關鍵字的用法
super
關鍵字用於引用父類中的屬性、方法和構造器。
示例程式碼
class Parent {
String name = "Parent";
void show() {
System.out.println("Parent show()");
}
}
class Child extends Parent {
String name = "Child";
void show() {
super.show(); // 呼叫父類的show方法
System.out.println("Child show(), name = " + name);
}
}
public class TestSuper {
public static void main(String[] args) {
Child obj = new Child();
obj.show();
}
}
final
關鍵字的用法
final
關鍵字可以用於修飾類、方法和變數。
- final類:不能被繼承。
- final方法:不能被重寫。
- final變數:一旦賦值後,其值不能被改變。
示例程式碼
final class FinalClass {
// ...
}
class MyClass {
final void show() {
// ...
}
}
public class TestFinal {
public static void main(String[] args) {
final int num = 10; // final變數
// num = 20; // 編譯錯誤:不能為final變數賦值
}
}
透過上述內容,你應該對繼承有了基本的瞭解,包括它的概念、優點、缺點、方法重寫規則以及super
和final
關鍵字的用法。希望這些示例程式碼能幫助你更好地理解這些概念。