網(wǎng)站建設(shè)專業(yè)簡介優(yōu)化營商環(huán)境心得體會個人
Java類的知識進(jìn)階
類的繼承(擴(kuò)張類)
Java類的繼承是指一個類可以繼承另一個類的屬性和方法,從而使得子類可以重用父類的代碼。繼承是面向?qū)ο缶幊讨械闹匾拍?#xff0c;它可以幫助我們避免重復(fù)編寫代碼,提高代碼的復(fù)用性和可維護(hù)性。
在Java中,使用關(guān)鍵字extends來實(shí)現(xiàn)繼承。子類繼承父類后,可以使用父類中的屬性和方法,同時還可以增加自己的屬性和方法。父類中的屬性和方法可以使用protected關(guān)鍵字來保護(hù),這樣子類就可以訪問這些屬性和方法。
當(dāng)子類繼承父類時,子類可以重寫父類的方法,從而實(shí)現(xiàn)子類自己的功能。子類也可以使用super關(guān)鍵字來調(diào)用父類的構(gòu)造方法和方法。
Java中的繼承是單繼承的,即一個子類只能繼承一個父類。但是,Java中可以通過接口實(shí)現(xiàn)多繼承,一個類可以實(shí)現(xiàn)多個接口。
繼承有助于代碼的復(fù)用和擴(kuò)展,但是也需要注意繼承的合理使用。過度的繼承會導(dǎo)致代碼的復(fù)雜性和耦合性增加,同時也會影響代碼的性能。因此,在使用繼承時需要根據(jù)具體情況進(jìn)行合理的設(shè)計和使用。
繼承父類的構(gòu)造函數(shù)
Java中,子類繼承父類的構(gòu)造函數(shù)有以下幾種情況:
-
如果子類沒有定義構(gòu)造函數(shù),則默認(rèn)繼承父類的無參構(gòu)造函數(shù)。
-
如果子類定義了構(gòu)造函數(shù),則需要在構(gòu)造函數(shù)中顯式調(diào)用父類的構(gòu)造函數(shù),可以使用super關(guān)鍵字來調(diào)用父類的構(gòu)造函數(shù)。例如:
public class Parent {public Parent(int x) {// 父類構(gòu)造函數(shù)}
}public class Child extends Parent {public Child(int x) {super(x); // 調(diào)用父類構(gòu)造函數(shù)// 子類構(gòu)造函數(shù)}
}
- 如果父類沒有無參構(gòu)造函數(shù),而子類又沒有顯式調(diào)用父類的構(gòu)造函數(shù),則編譯器會報錯。這時,需要在子類的構(gòu)造函數(shù)中顯式調(diào)用父類的某個構(gòu)造函數(shù)。例如:
public class Parent {public Parent(int x) {// 父類構(gòu)造函數(shù)}
}public class Child extends Parent {public Child() {super(0); // 調(diào)用父類構(gòu)造函數(shù)// 子類構(gòu)造函數(shù)}
}
創(chuàng)建子類的對象
在Java中創(chuàng)建子類的對象,可以使用以下步驟:
-
定義一個子類,該子類繼承自父類。
-
在子類中定義構(gòu)造函數(shù),可以使用super關(guān)鍵字調(diào)用父類的構(gòu)造函數(shù)。
-
在主程序中創(chuàng)建子類的對象,可以使用子類的構(gòu)造函數(shù)來創(chuàng)建對象。
例如,以下是一個簡單的例子,演示如何創(chuàng)建子類的對象:
class Animal {public void eat() {System.out.println("Animal is eating");}
}class Dog extends Animal {public void bark() {System.out.println("Dog is barking");}
}public class Main {public static void main(String[] args) {Dog dog = new Dog();dog.eat(); //調(diào)用父類的方法dog.bark(); //調(diào)用子類的方法}
}
在這個例子中,Animal類是父類,Dog類是子類。在Dog類中定義了一個bark()方法,該方法是子類特有的方法。在主程序中創(chuàng)建了一個Dog對象,然后調(diào)用了父類的方法和子類的方法。
調(diào)用父類的構(gòu)造函數(shù)
在Java中,可以使用super關(guān)鍵字來調(diào)用父類的構(gòu)造函數(shù)。super關(guān)鍵字必須放在子類構(gòu)造函數(shù)的第一行,并且只能調(diào)用一次。調(diào)用父類構(gòu)造函數(shù)的語法如下:
public class SubClass extends SuperClass {public SubClass() {super(); // 調(diào)用父類無參構(gòu)造函數(shù)}public SubClass(int arg) {super(arg); // 調(diào)用父類有參構(gòu)造函數(shù)}
}
在子類構(gòu)造函數(shù)中使用super關(guān)鍵字調(diào)用父類構(gòu)造函數(shù)時,可以使用無參構(gòu)造函數(shù)或有參構(gòu)造函數(shù)。如果不調(diào)用父類構(gòu)造函數(shù),則會默認(rèn)調(diào)用父類的無參構(gòu)造函數(shù)。
指定父類的構(gòu)造函數(shù)
在Java中,可以使用super關(guān)鍵字來調(diào)用父類的構(gòu)造函數(shù)。下面是指定父類構(gòu)造函數(shù)的語法:
class Subclass extends Superclass {Subclass() {super(); // 調(diào)用父類的默認(rèn)構(gòu)造函數(shù)}Subclass(int x) {super(x); // 調(diào)用父類的帶參構(gòu)造函數(shù)}
}
在子類的構(gòu)造函數(shù)中,使用super關(guān)鍵字來調(diào)用父類的構(gòu)造函數(shù)。如果父類有多個構(gòu)造函數(shù),可以根據(jù)需要選擇調(diào)用哪一個構(gòu)造函數(shù)。需要注意的是,如果子類的構(gòu)造函數(shù)沒有顯式地調(diào)用父類的構(gòu)造函數(shù),Java會默認(rèn)調(diào)用父類的默認(rèn)構(gòu)造函數(shù)。
在子類內(nèi)部存取
父類中protected或public
父類的成員變量和方法,可以使用super關(guān)鍵字來訪問。例如,如果父類有一個名為“age”的成員變量和一個名為“getName”的方法,子類可以使用以下代碼來訪問它們:
public class Parent {protected int age;protected String getName() {return "Parent";}
}public class Child extends Parent {public void printInfo() {// 訪問父類的成員變量System.out.println(super.age);// 調(diào)用父類的方法System.out.println(super.getName());}
}
在子類中,super.age表示訪問父類的age成員變量,super.getName()表示調(diào)用父類的getName方法。注意,這里使用了protected修飾符來使父類的成員變量和方法對子類。可見如果沒有使用protected或public修飾符,子類將無法訪問它們。
父類有私有變量時,需要使用getter和setter方法。這是因為,私有變量只能在本類中訪問,無法被子類直接訪問。所以,我們需要在父類中定義公共的getter和setter方法,以便子類可以通過這些方法訪問父類的私有變量。
例如,假設(shè)我們有一個父類Person,其中有一個私有變量name:
public class Person {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}
}
在子類Student中,如果我們想要訪問父類Person的name變量,就需要使用父類的getter和setter方法:
public class Student extends Person {public void printName() {System.out.println(getName());}public void changeName(String newName) {setName(newName);}
}
在printName方法中,我們使用了父類的getName方法來獲取name變量的值。在changeName方法中,我們使用了父類的setName方法來修改name變量的值。這樣,我們就可以在子類中存取父類的私有變量了。
重載
重載方法
Java中,類中可以定義多個同名方法,只要它們的參數(shù)列表不同,這就是方法重載(overloading)。
方法重載的規(guī)則:
-
方法名必須相同
-
參數(shù)列表必須不同(個數(shù)不同或者類型不同,順序不同也算)
-
方法的返回類型可以相同也可以不同
-
僅僅返回類型不同不足以成為方法的重載
例子:
public class MyClass {public void print(int x) {System.out.println("This is an integer: " + x);}public void print(String x) {System.out.println("This is a string: " + x);}public void print(int x, String y) {System.out.println("This is an integer: " + x + " and this is a string: " + y);}
}
在上面的例子中,MyClass類中定義了三個print方法。第一個print方法接收一個整型參數(shù),第二個print方法接收一個字符串參數(shù),第三個print方法接收一個整型參數(shù)和一個字符串參數(shù)。這三個方法的方法名相同,但是它們的參數(shù)列表不同,因此它們構(gòu)成了方法的重載。
用父類的參數(shù)處理對象
在Java中,可以使用父類的參數(shù)來處理對象。這通常涉及到使用繼承和多態(tài)性的概念。
首先,在父類中定義一個參數(shù)類型為父類的方法,該方法將接收一個父類的對象作為參數(shù)。然后,在子類中重寫該方法,并使用子類的對象來調(diào)用它。
例如,假設(shè)有一個Animal類和一個Dog類繼承自它。Animal類有一個方法叫做makeSound(),它接收一個Animal對象作為參數(shù)并打印出該對象的聲音。在Dog類中,可以重寫makeSound()方法,并使用Dog對象來調(diào)用它。
下面是一個示例代碼:
public class Animal {public void makeSound(Animal a) {System.out.println("This animal makes a sound");}
}public class Dog extends Animal {@Overridepublic void makeSound(Animal a) {System.out.println("This dog barks");}public static void main(String[] args) {Animal animal = new Animal();Dog dog = new Dog();animal.makeSound(animal); // prints "This animal makes a sound"dog.makeSound(dog); // prints "This dog barks"animal.makeSound(dog); // prints "This animal makes a sound"}
}
在此示例中,Animal類有一個makeSound()方法,它接收一個Animal對象作為參數(shù)并打印出該對象的聲音。Dog類繼承自Animal類,并重寫了makeSound()方法,以便使用Dog對象來打印出狗的聲音。
在main()方法中,創(chuàng)建了一個Animal對象和一個Dog對象。然后,使用這些對象來調(diào)用makeSound()方法,以便演示使用父類的參數(shù)來處理對象的概念。
方法重載的重要性
Java方法重載的重要性在于可以提高代碼的可讀性和可維護(hù)性。通過方法重載,可以使用相同的方法名來實(shí)現(xiàn)不同的功能,使代碼更加簡潔和易于理解。同時,方法重載還可以避免使用過多的方法名,減少代碼的冗余和重復(fù),提高代碼的重用性。此外,方法重載還可以使代碼更加靈活,能夠適應(yīng)不同的需求和情況,提高代碼的適應(yīng)性和擴(kuò)展性??傊?#xff0c;Java方法重載是Java編程中非常重要的一部分,可以提高代碼質(zhì)量和開發(fā)效率。
使用與父類相同名稱的成員
在Java中,如果一個子類想要使用與父類相同名稱的成員變量或方法,可以使用super關(guān)鍵字來引用父類的成員。
對于成員變量,可以使用super關(guān)鍵字來訪問父類的成員變量。例如:
public class Parent {public int x = 10;
}public class Child extends Parent {public int x = 20;public void printX() {System.out.println("Child x: " + x); // 輸出20System.out.println("Parent x: " + super.x); // 輸出10}
}
對于成員方法,可以使用super關(guān)鍵字來調(diào)用父類的方法。例如:
public class Parent {public void print() {System.out.println("Parent");}
}public class Child extends Parent {public void print() {System.out.println("Child");super.print(); // 調(diào)用父類的print方法}
}
使用super關(guān)鍵字可以方便地在子類中使用與父類相同名稱的成員。
添加final
在Java中,可以使用關(guān)鍵字final來修飾類,表示該類不能被繼承。在類的定義前加上關(guān)鍵字final即可。
例如:
final public class MyClass {// 類的成員變量和方法
}
這樣定義的類MyClass就是一個final類,不能被其他類繼承。
需要注意的是,如果一個類被聲明為final,那么它的所有方法都默認(rèn)為final方法,即不能被子類重寫。如果需要允許子類重寫某個方法,可以在該方法前加上關(guān)鍵字override。
Object類的繼承
創(chuàng)建類的階層
- 定義類名和訪問修飾符
- 定義類的屬性,包括變量和常量
- 定義類的構(gòu)造方法,用于初始化對象
- 定義類的方法,包括普通方法、靜態(tài)方法和抽象方法
- 定義類的內(nèi)部類或枚舉類型
- 重寫Object類的方法,如equals、hashCode和toString方法
- 實(shí)現(xiàn)接口,包括單個接口和多個接口
- 定義類的靜態(tài)代碼塊或?qū)嵗a塊
- 定義類的內(nèi)部類或枚舉類型的構(gòu)造方法、方法和屬性
- 定義類的內(nèi)部類或枚舉類型的靜態(tài)代碼塊或?qū)嵗a塊
了解Object類
Java Object類是所有Java類的超類,它定義了所有Java類都具有的默認(rèn)行為。Object類有以下幾個重要的方法:
-
equals():比較兩個對象是否相等。默認(rèn)實(shí)現(xiàn)是比較兩個對象的內(nèi)存地址,可以被子類重寫以定義自己的相等邏輯。
-
hashCode():返回對象的哈希碼。默認(rèn)實(shí)現(xiàn)是返回對象的內(nèi)存地址的哈希碼,可以被子類重寫以定義自己的哈希碼計算邏輯。
-
toString():返回對象的字符串表示。默認(rèn)實(shí)現(xiàn)是返回類名和對象的內(nèi)存地址的字符串表示,可以被子類重寫以定義自己的字符串表示邏輯。
-
getClass():返回對象的類對象。
-
notify()和notifyAll():用于多線程同步,喚醒等待在對象上的線程。
-
wait():用于多線程同步,使當(dāng)前線程等待,直到其他線程調(diào)用notify()或notifyAll()方法喚醒它。
Object類是Java語言中最基本的類,所有的Java對象都直接或間接繼承自O(shè)bject類。因此,Object類的方法對Java程序的編寫和調(diào)試都具有非常重要的意義。
定義toString()方法
在Java中,toString()方法是一個Object類中的方法,它用于返回對象的字符串表示形式。如果沒有重寫該方法,則默認(rèn)實(shí)現(xiàn)返回一個包含對象類名和哈希碼的字符串。
在實(shí)際應(yīng)用中,程序員通常會根據(jù)自己的需要重寫toString()方法,以便更好地描述對象的狀態(tài)和屬性。例如,可以使用該方法將對象的各個屬性以字符串形式連接起來,以便于輸出和調(diào)試。
以下是一個示例代碼,展示如何重寫toString()方法:
public class Person {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Person [name=" + name + ", age=" + age + "]";}
}
在上面的示例中,我們重寫了toString()方法,將Person對象的name和age屬性以字符串形式輸出。當(dāng)我們在程序中調(diào)用該方法時,就會得到一個包含這些信息的字符串。
例如,下面的代碼片段將創(chuàng)建一個Person對象,并輸出它的字符串表示形式:
Person p = new Person("Alice", 25);
System.out.println(p.toString());
輸出結(jié)果如下:
Person [name=Alice, age=25]
使用equals()方法
Java中的equals()方法是用來比較兩個對象是否相等的方法。在Java中,所有的類都繼承了Object類,Object類中有一個equals()方法,但是它的默認(rèn)實(shí)現(xiàn)是比較兩個對象的引用地址是否相等,即是否為同一個對象。因此,如果我們想要比較兩個對象的內(nèi)容是否相等,就需要重寫equals()方法。
重寫equals()方法的步驟如下:
-
檢查傳入的對象是否為null,如果為null,直接返回false。
-
檢查傳入的對象是否為當(dāng)前對象的實(shí)例,如果是,直接返回true。
-
檢查傳入的對象是否屬于同一個類,如果不是,直接返回false。
-
將傳入的對象轉(zhuǎn)換為當(dāng)前類的實(shí)例。
-
比較當(dāng)前對象的每個屬性是否與傳入對象的屬性相等,如果有任何一個屬性不相等,直接返回false。
-
如果所有屬性都相等,返回true。
下面是一個示例代碼,演示如何重寫equals()方法:
public class Person {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}@Overridepublic boolean equals(Object obj) {if (obj == null) {return false;}if (this == obj) {return true;}if (getClass() != obj.getClass()) {return false;}Person other = (Person) obj;if (name == null) {if (other.name != null) {return false;}} else if (!name.equals(other.name)) {return false;}if (age != other.age) {return false;}return true;}
}
在這個示例中,我們重寫了Person類的equals()方法,比較了兩個Person對象的name和age屬性是否相等。如果兩個Person對象的name和age屬性都相等,那么equals()方法就會返回true,否則返回false。
使用getClass()方法
在Java中,getClass()方法是Object類中的一個方法,可以用來獲取一個對象的運(yùn)行時類。它的語法如下:
public final Class<?> getClass()
該方法返回一個Class對象,該對象表示當(dāng)前對象所屬的類。例如:
public class MyClass {public static void main(String[] args) {MyClass obj = new MyClass();Class<?> c = obj.getClass();System.out.println(c.getName());}
}
在上面的代碼中,我們創(chuàng)建了一個MyClass對象,并調(diào)用了它的getClass()方法來獲取它的運(yùn)行時類。然后我們使用Class對象的getName()方法來獲取該類的名稱,并將其打印到控制臺上。運(yùn)行結(jié)果為:
MyClass
這說明getClass()方法確實(shí)返回了當(dāng)前對象所屬的MyClass類。