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