筆者畢業於台灣地區的台灣海洋大學通訊與導航工程學系,今年4月參加資展國際的後端班培訓,到九月才結訓。以下是我用來記錄上課用筆記,可能偏向於我們地區的公司面試,所以有可能與內地用語或是準備方面不完全相同,想看就加減看看吧,反正不虧XD
<基礎部分>
1、何謂物件導向程式設計(OOP):
繼承:
繼承是從已經有的類別(父類或基礎類別)得到屬性和方法,並建立新的類別(子類或衍生類別)的過程。繼承允許子類別重用父類別的程式碼,並根據需求擴展或修改父類別的功能。這種方式有助於提高程式的可重用性和可維護性。
//父類
class Animal{
void makeSound(){
System.out.print("叫聲");
}
}
//子類
class Dog extends Animal{
@Override
void makeSound(){
System.out.print("汪汪汪");
}
}
public class Main {
public static void main(String[] args) {
Animal myDog = new Dog();
myDog.makeSound();
}
}
封裝:
封裝是將資料(屬性)和操作資料的方法(行為)綁再一起,將物件的內部狀態和行為封裝起來,對外只暴露有限的接口。通過封裝,可以保護物件的內部狀態不被外部隨意改變,只能通過定義好的方法來存取和修改內部狀態,這樣即可增加資安和程式的可護性。
// 封裝示例 - BankAccount 類別
class BankAccount {
// 私有屬性,僅類別內部可訪問
private String accountNumber;
private double balance;
// 公有建構子,用於初始化 BankAccount 物件
public BankAccount(String accountNumber, double initialBalance) {
this.accountNumber = accountNumber;
this.balance = initialBalance;
}
// 公有方法,用於存款
public void deposit(double amount) {
if (amount > 0) {
balance += amount;
} else {
System.out.println("存款金額必須大於零");
}
}
// 公有方法,用於提款
public void withdraw(double amount) {
if (amount > 0 && amount <= balance) {
balance -= amount;
} else {
System.out.println("提款金額無效或餘額不足");
}
}
// 公有方法,用於查詢餘額
public double getBalance() {
return balance;
}
// 公有方法,用於獲取帳號
public String getAccountNumber() {
return accountNumber;
}
}
// 主程式
public class Main {
public static void main(String[] args) {
// 建立 BankAccount 物件
BankAccount myAccount = new BankAccount("123456789", 1000.0);
// 存款
myAccount.deposit(500.0);
System.out.println("餘額: " + myAccount.getBalance()); // 輸出: 餘額: 1500.0
// 提款
myAccount.withdraw(200.0);
System.out.println("餘額: " + myAccount.getBalance()); // 輸出: 餘額: 1300.0
// 嘗試存入無效金額
myAccount.deposit(-100.0); // 輸出: 存款金額必須大於零
// 嘗試提取無效金額
myAccount.withdraw(2000.0); // 輸出: 提款金額無效或餘額不足
}
}
多型:
只在多個不同的子類別物件中,對相同的訊息或方法呼叫可以做出不同的回應。意味著父類別的引用可以指向不同的子類別物件,且在執行時根據實際指向的物件類型來調用相對應的方法。多行有助於提高程式的靈活和拓展性,使得程式能夠處理不同類型的物件而不用更改原有的程式碼。
// 父類別 - 動物
class Animal {
// 父類別的方法
void makeSound() {
System.out.println("叫聲");
}
}
// 子類別 - 狗
class Dog extends Animal {
// 覆蓋父類別的方法
@Override
void makeSound() {
System.out.println("汪汪汪");
}
}
// 子類別 - 貓
class Cat extends Animal {
// 覆蓋父類別的方法
@Override
void makeSound() {
System.out.println("喵喵喵");
}
}
// 子類別 - 牛
class Cow extends Animal {
// 覆蓋父類別的方法
@Override
void makeSound() {
System.out.println("哞哞哞");
}
}
// 主程式
public class Main {
public static void main(String[] args) {
// 使用父類別引用指向不同的子類別物件
Animal myDog = new Dog();
Animal myCat = new Cat();
Animal myCow = new Cow();
// 呼叫 makeSound 方法,多態性展示
myDog.makeSound();
myCat.makeSound();
myCow.makeSound();
}
}
2.重載(Overloading)和重寫(Overriding)
| 區別項目 | 重載(Overloading) | 重寫(Overriding) |
|---|---|---|
| 發生位置 | 同一個類別中 | 父類別與子類別之間 |
| 方法名稱 | 必須相同 | 必須相同 |
| 參數清單(Parameter List) | 必須不同(參數的數量或類型不同) | 必須相同 |
| 返回值類型(Return Type) | 可以不同 | 必須相同 |
| 存取權限(Access Modifier) | 可以不同 | 不能比父類別中的方法存取權限更低 |
| 靜態方法(Static Methods) | 可以重載 | 不能重寫(但可以隱藏父類別的靜態方法) |
| 建構子(Constructors) | 可以重載 | 不能重寫 |
| 標註(Annotations) | 不需要標註 | 需要 @Override 標註 |
// Overload
class MathOperation {
// 重載方法 add,接受兩個整數參數
int add(int a, int b) {
return a + b;
}
// 重載方法 add,接受三個整數參數
int add(int a, int b, int c) {
return a + b + c;
}
// 重載方法 add,接受兩個雙精度浮點數參數
double add(double a, double b) {
return a + b;
}
}
public class Main {
public static void main(String[] args) {
MathOperation math = new MathOperation();
System.out.println("Sum of 2 and 3: " + math.add(2, 3));
System.out.println("Sum of 1, 2 and 3: " + math.add(1, 2, 3));
System.out.println("Sum of 1.5 and 2.5: " + math.add(1.5, 2.5));
}
}
// Overriding
// 父類別 - Animal
class Animal {
void makeSound() {
System.out.println("動物叫聲");
}
}
// 子類別 - Dog
class Dog extends Animal {
@Override
void makeSound() {
System.out.println("汪");
}
}
// 子類別 - Cat
class Cat extends Animal {
@Override
void makeSound() {
System.out.println("喵");
}
}
public class Main {
public static void main(String[] args) {
Animal myAnimal = new Animal();
Animal myDog = new Dog();
Animal myCat = new Cat();
myAnimal.makeSound();
myDog.makeSound();
myCat.makeSound();
}
}
3.介面(Interface)與抽象類別(Abstract Class)的區別
| 區別項目 | 介面(Interface) | 抽象類別(Abstract Class) |
|---|---|---|
| 繼承與實現 | 類別實現(implement)介面 | 類別繼承(extend)抽象類別 |
| 多繼承 | 介面可以多繼承其他介面 | 類別只能單繼承 |
| 建構子 | 介面不能有建構子 | 抽象類別可以有建構子 |
| 成員變數 | 介面只能宣告常數(static final 變數) | 抽象類別可以有成員變數 |
| 方法修飾符 | 介面的方法只能是 public 且預設為 public abstract | 抽象類別的方法可以有 public、protected 和 default 修飾符 |
| 實例化 | 介面不能被實例化 | 抽象類別不能被實例化,除這點外,與普通類別無異 |
| 方法體 | 介面中的方法默認為抽象方法,Java 8 之後可以有 default 和 static 方法有方法體 | 抽象類別可以有抽象方法和具體方法 |
| 預設方法 | Java 8 之後介面可以有 default 方法 | 抽象類別可以有具體方法 |
// Interface
// 定義介面
interface Animal {
void makeSound(); // 介面中的方法預設為 public abstract
void eat(); // 介面中的方法預設為 public abstract
}
// 類別實現介面
class Dog implements Animal {
@Override
public void makeSound() {
System.out.println("汪汪汪");
}
@Override
public void eat() {
System.out.println("dog with a bone");
}
}
// 類別實現介面
class Cat implements Animal {
@Override
public void makeSound() {
System.out.println("喵喵喵");
}
@Override
public void eat() {
System.out.println("Cat eats fish");
}
}
public class Main {
public static void main(String[] args) {
Animal myDog = new Dog();
Animal myCat = new Cat();
myDog.makeSound();
myDog.eat();
myCat.makeSound();
myCat.eat();
}
}
// Abstract
// 定義抽象類別
abstract class Animal {
abstract void makeSound(); // 抽象方法
void sleep() { // 具體方法
System.out.println("Animal is sleeping");
}
}
// 繼承抽象類別
class Dog extends Animal {
@Override
void makeSound() {
System.out.println("汪汪汪");
}
}
// 繼承抽象類別
class Cat extends Animal {
@Override
void makeSound() {
System.out.println("喵喵喵");
}
}
public class Main {
public static void main(String[] args) {
Animal myDog = new Dog();
Animal myCat = new Cat();
myDog.makeSound();
myDog.sleep();
myCat.makeSound();
myCat.sleep();
}
}
4.深拷貝與淺拷貝的理解
淺拷貝: 複製物件時,只複製原物件的基本型別屬性和引用類型屬性的引用,部會複製引用指向的實際物件。結果是新舊物件共享同一個引用類型成員
深拷貝: 複製物件時,會遞歸地複製所有引用類型屬性,確保新物件與原物件完全獨立,沒有共享的成員。
總結: 如果希望新舊物件之間保持獨立,應該使用深拷貝;不介意則用淺拷貝。
5.sleep 和 wait 方法的區別
| 區別項目 | sleep 方法 |
wait 方法 |
|---|---|---|
| 所屬類別 | Thread |
Object |
| 釋放 CPU | 釋放 | 釋放 |
| 釋放鎖定資源 | 不釋放 | 釋放 |
| 使用方式 | Thread.sleep(時間) |
wait(時間) 或 wait() |
| 喚醒方式 | 自動喚醒,等待時間結束 | 通過 notify 或 notifyAll 喚醒,或等待時間結束 |
| 必須處理的異常 | InterruptedException |
InterruptedException |
| 必須在同步代碼塊或同步方法中使用 | 否 | 是 |
| 其他要求 | 無 | 必須與 synchronized 一起使用 |
// sleep
class SleepExample {
public static void main(String[] args) {
Thread thread = new Thread(()

最低0.47元/天 解锁文章
2833

被折叠的 条评论
为什么被折叠?



