一、構(gòu)造方法
在Java中,構(gòu)造方法是一種特殊的方法,它的主要作用是用于創(chuàng)建對象時初始化對象。構(gòu)造方法的名稱必須與類名完全相同,并且不返回任何值,也不定義返回類型(包括void)。構(gòu)造方法可以有參數(shù),也可以沒有參數(shù)。
構(gòu)造方法的定義
1、無參構(gòu)造方法:
public class MyClass {
public MyClass() {
// 初始化代碼
}
}
2、帶參構(gòu)造方法:
public class MyClass {
private String name;
private int age;
public MyClass(String name, int age) {
this.name = name;
this.age = age;
}
}
構(gòu)造方法的重載
你可以在同一個類中定義多個構(gòu)造方法,只要它們的參數(shù)列表不同(即參數(shù)的類型、數(shù)量或順序不同)。這稱為構(gòu)造方法的重載。
public class MyClass {
private String name;
private int age;
// 無參構(gòu)造方法
public MyClass() {
this.name = "Unknown";
this.age = 0;
}
// 帶一個String參數(shù)的構(gòu)造方法
public MyClass(String name) {
this.name = name;
this.age = 0; // 或者其他默認值
}
// 帶兩個參數(shù)的構(gòu)造方法
public MyClass(String name, int age) {
this.name = name;
this.age = age;
}
}
調(diào)用構(gòu)造方法
當你創(chuàng)建一個類的實例時,至少會調(diào)用一個構(gòu)造方法。如果沒有明確調(diào)用其他構(gòu)造方法(通過this關(guān)鍵字),Java將自動調(diào)用無參的構(gòu)造方法。如果你在類中定義了其他構(gòu)造方法,并且想從另一個構(gòu)造方法中初始化對象的狀態(tài),可以使用this關(guān)鍵字調(diào)用其他構(gòu)造方法。例如:
public class MyClass {
private String name;
private int age;
private double height; // 新增一個字段和構(gòu)造方法
public MyClass() { // 無參構(gòu)造方法,可以省略,因為Java會提供一個默認的無參構(gòu)造方法,除非你定義了其他構(gòu)造方法。
this("Unknown", 0, 0.0); // 調(diào)用帶三個參數(shù)的構(gòu)造方法
}
public MyClass(String name) { // 帶一個String參數(shù)的構(gòu)造方法,調(diào)用帶兩個參數(shù)的構(gòu)造方法并設(shè)置height為默認值。
this(name, 0, 0.0); // 使用this調(diào)用另一個構(gòu)造方法,傳遞name和默認的age和height。
}
public MyClass(String name, int age) { // 帶兩個參數(shù)的構(gòu)造方法,調(diào)用帶三個參數(shù)的構(gòu)造方法并設(shè)置height為默認值。
this(name, age, 0.0); // 使用this調(diào)用另一個構(gòu)造方法,傳遞name和age以及默認的height。
}
public MyClass(String name, int age, double height) { // 帶三個參數(shù)的構(gòu)造方法。
this.name = name;
this.age = age;
this.height = height; // 新增字段的初始化。
}
}
在這個例子中,this關(guān)鍵字被用來在一個構(gòu)造方法中調(diào)用另一個構(gòu)造方法,這是一種常見的做法,特別是在你想要重用初始化代碼時。注意,this調(diào)用必須是構(gòu)造方法的第一個語句。
二、封裝
在Java中,封裝(Encapsulation)是面向?qū)ο缶幊蹋∣OP)的四大基本特性之一,它指的是將對象的狀態(tài)(屬性)和行為(方法)綁定在一起,并對外隱藏對象的細節(jié),僅通過公共的接口提供訪問和操作對象的方法。這樣做的好處是可以保護對象內(nèi)部的狀態(tài),防止外部代碼直接訪問和修改,同時可以控制對數(shù)據(jù)的訪問,確保數(shù)據(jù)的安全性和完整性。
實現(xiàn)封裝的步驟
1、定義私有屬性:首先,將類的屬性定義為私有(private),這樣外部代碼就不能直接訪問這些屬性。
2、提供公共的getter和setter方法:然后,為每個私有屬性提供公共的getter(訪問器)和setter(修改器)方法。通過這些方法,你可以控制對屬性的訪問和修改,例如可以進行輸入驗證、執(zhí)行額外的邏輯等。
3、使用構(gòu)造器:構(gòu)造器用于初始化對象的狀態(tài)。通過構(gòu)造器傳遞參數(shù)給私有屬性,可以在對象創(chuàng)建時設(shè)置其初始狀態(tài)。
示例代碼
public class Person {
// 私有屬性
private String name;
private int age;
// 構(gòu)造器
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// Getter方法
public String getName() {
return name;
}
// Setter方法
public void setName(String name) {
this.name = name;
}
// Getter方法
public int getAge() {
return age;
}
// Setter方法,這里可以添加一些邏輯,例如年齡檢查
public void setAge(int age) {
if (age > 0) { // 簡單的年齡驗證
this.age = age;
} else {
System.out.println("年齡必須大于0");
}
}
}
封裝的好處
- 提高安全性:保護對象內(nèi)部狀態(tài),防止外部代碼隨意修改。
- 提高靈活性:可以在setter方法中添加邏輯,例如驗證輸入、執(zhí)行額外的操作等。
- 便于維護:當類的內(nèi)部實現(xiàn)發(fā)生變化時(例如屬性名改變),只需修改類的內(nèi)部實現(xiàn)而不需要修改外部代碼。
- 促進團隊合作:封裝使得團隊成員不必了解類的內(nèi)部實現(xiàn)細節(jié),只需通過公共接口與對象交互。
三、繼承
在Java中,繼承是一種面向?qū)ο缶幊痰臋C制,它允許我們定義一個類(稱為子類或派生類)繼承另一個類(稱為父類或基類)的屬性和方法。通過繼承,我們可以重用代碼,實現(xiàn)代碼的共享,并促進代碼的組織和模塊化。
繼承的基本語法
- 使用extends關(guān)鍵字來實現(xiàn)繼承。
- 子類重寫父類方法:方法名、參數(shù)列表相同
- 權(quán)限不能更低
- @Override 注解(推薦)
- super 關(guān)鍵字:super.成員變量:訪問父類變量,super.成員方法():調(diào)用父類方法,super(...):調(diào)用父類構(gòu)造方法(必須第一行)
class ParentClass {
// 父類的屬性和方法
}
class ChildClass extends ParentClass {
// 子類的屬性和方法
}
示例
假設(shè)我們有一個Vehicle類,表示一般的交通工具,我們希望有一個Car類表示汽車,它是一種特殊的交通工具。
// 父類:Vehicle
class Vehicle {
String color;
int maxSpeed;
Vehicle(String color, int maxSpeed) {
this.color = color;
this.maxSpeed = maxSpeed;
}
@Override
void displayInfo() {
System.out.println("Color: " + color + ", Max Speed: " + maxSpeed);
}
}
// 子類:Car
class Car extends Vehicle {
int numDoors;
Car(String color, int maxSpeed, int numDoors) {
super(color, maxSpeed); // 調(diào)用父類的構(gòu)造器
this.numDoors = numDoors;
}
void displayDoors() {
System.out.println("Number of Doors: " + numDoors);
}
}
使用子類對象
public class TestInheritance {
public static void main(String[] args) {
Car myCar = new Car("Red", 200, 4); // 使用子類構(gòu)造器創(chuàng)建對象
myCar.displayInfo(); // 調(diào)用從父類繼承的方法
myCar.displayDoors(); // 調(diào)用子類自己的方法
}
}
注意事項和最佳實踐
1、單一繼承:Java不支持多重繼承(即一個類繼承多個類)。但是,通過接口(Interface)可以實現(xiàn)類似多重繼承的功能。
2、訪問修飾符:子類可以訪問父類的公有(public)和受保護(protected)成員,但不能訪問私有(private)成員。如果需要訪問私有成員,可以通過公共方法(getter和setter)。
3、構(gòu)造器:子類的構(gòu)造器默認會調(diào)用父類的無參構(gòu)造器。如果父類沒有無參構(gòu)造器,則需要在子類的構(gòu)造器中顯式調(diào)用父類的其他構(gòu)造器。使用super關(guān)鍵字。
4、方法重寫:子類可以重寫父類的方法。當調(diào)用方法時,將執(zhí)行子類中重寫的方法,除非使用super關(guān)鍵字調(diào)用父類的方法。
5、多態(tài)性:通過繼承和多態(tài)性,可以在運行時決定調(diào)用哪個類的哪個方法。這是面向?qū)ο缶幊痰膹姶蠊δ苤弧?/p>
四、多態(tài)
在Java中,多態(tài)(Polymorphism)是一種允許對象在運行時表現(xiàn)出不同的形式的能力。它是面向?qū)ο缶幊蹋∣OP)中的一個核心概念,主要體現(xiàn)在以下幾個方面:
- 父類引用指向子類對象
- 編譯看左邊,運行看右邊
- 向上轉(zhuǎn)型(自動):父類 引用 = new 子類();
- 向下轉(zhuǎn)型(強制):子類 引用 = (子類) 父類引用;
- instanceof:判斷對象真實類型
- 多態(tài)好處:統(tǒng)一調(diào)用、擴展性強
1、方法重寫(Method Overriding)
多態(tài)主要通過方法重寫實現(xiàn)。當一個類繼承另一個類時,子類可以重寫父類中的方法,以提供特定的實現(xiàn)。這樣,當使用父類類型的引用調(diào)用被重寫的方法時,實際執(zhí)行的是子類中定義的方法。
示例代碼:
class Animal {
void sound() {
System.out.println("Animal makes a sound");
}
}
class Dog extends Animal {
@Override
void sound() {
System.out.println("Dog bark");
}
}
public class TestPolymorphism {
public static void main(String[] args) {
Animal myAnimal = new Dog(); // 父類引用指向子類對象
myAnimal.sound(); // 輸出: Dog bark
}
}
2、接口實現(xiàn)(Interface Implementation)
在Java中,接口也可以實現(xiàn)多態(tài)。通過實現(xiàn)接口,不同的類可以實現(xiàn)同一接口的多個版本。
- 完全抽象(Java 8 前)
- 方法默認 public abstract
- 變量默認 public static final
- 類實現(xiàn)接口:implements
- 一個類可以實現(xiàn)多個接口
示例代碼:
interface Animal {
void sound();
}
class Dog implements Animal {
public void sound() {
System.out.println("Dog bark");
}
}
class Cat implements Animal {
public void sound() {
System.out.println("Cat meow");
}
}
public class TestPolymorphism {
public static void main(String[] args) {
Animal myAnimal1 = new Dog(); // 接口引用指向Dog對象
Animal myAnimal2 = new Cat(); // 接口引用指向Cat對象
myAnimal1.sound(); // 輸出: Dog bark
myAnimal2.sound(); // 輸出: Cat meow
}
}
3、抽象類(Abstract Class)與多態(tài)
抽象類也可以用來實現(xiàn)多態(tài),通過抽象類定義方法,由子類提供具體實現(xiàn)。
- 包含 abstract 方法的類
- 抽象方法只有聲明,沒有實現(xiàn)
- 抽象類不能實例化
- 子類必須重寫所有抽象方法,否則也得是抽象類
示例代碼:
abstract class Animal {
abstract void sound(); // 抽象方法,由子類實現(xiàn)
}
class Dog extends Animal {
void sound() {
System.out.println("Dog bark");
}
}
class Cat extends Animal {
void sound() {
System.out.println("Cat meow");
}
}
public class TestPolymorphism {
public static void main(String[] args) {
Animal myAnimal1 = new Dog(); // 抽象類引用指向Dog對象
Animal myAnimal2 = new Cat(); // 抽象類引用指向Cat對象
myAnimal1.sound(); // 輸出: Dog bark
myAnimal2.sound(); // 輸出: Cat meow
}
}