【Java面試題-基礎知識02】Java抽象類和介面六連問?

慕容尘轩發表於2024-03-14

1、抽象類和介面分別是什麼?

  • 抽象類是一種類,可以包含抽象方法和非抽象方法,抽象方法是沒有具體實現的方法,需要在子類中被具體實現。
  • 介面是一種完全抽象的類,其中的所有方法都是抽象方法,沒有方法體,它只是定義了一組方法的契約。

2、介面中一定不可以有實現方法嗎?

不一定,Java 8 引入了預設方法(Default Methods)的概念,允許在介面中包含具有預設實現的方法。

public interface MyInterface {
    // 抽象方法
    void abstractMethod();
    
    // 預設方法
    default void defaultMethod() {
        System.out.println("This is a default method in MyInterface.");
    }
}

3、抽象類和介面的使用場景?

  • 抽象類適合於那些有一定相似功能的類,其中一些方法需要在子類中實現,而其他方法已經實現了一部分,可以被子類直接繼承和複用。
// 抽象類 Animal
abstract class Animal {
    private String name;
    
    public Animal(String name) {
        this.name = name;
    }
    
    // 抽象方法,需要在子類中實現
    public abstract void makeSound();
    
    // 具體方法,被子類繼承和複用
    public void eat() {
        System.out.println(name + " is eating.");
    }
}

// 子類 Dog 繼承自抽象類 Animal
class Dog extends Animal {
    public Dog(String name) {
        super(name);
    }
    
    // 實現抽象方法
    @Override
    public void makeSound() {
        System.out.println("Dog " + super.name + " barks.");
    }
}

// 子類 Cat 繼承自抽象類 Animal
class Cat extends Animal {
    public Cat(String name) {
        super(name);
    }
    
    // 實現抽象方法
    @Override
    public void makeSound() {
        System.out.println("Cat " + super.name + " meows.");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog("Buddy");
        dog.makeSound(); // Output: Dog Buddy barks.
        dog.eat();       // Output: Buddy is eating.
        
        Cat cat = new Cat("Whiskers");
        cat.makeSound(); // Output: Cat Whiskers meows.
        cat.eat();       // Output: Whiskers is eating.
    }
}
  • 介面適合於定義類的行為,而不關心類的內部資料狀態。如果多個不同類具有相同的行為,但是其內部實現不同,可以透過介面來實現這種行為的統一。

  

// 定義介面 Animal
interface Animal {
    void makeSound();
}

// 實現介面 Animal 的類 Dog
class Dog implements Animal {
    @Override
    public void makeSound() {
        System.out.println("Dog barks.");
    }
}

// 實現介面 Animal 的類 Cat
class Cat implements Animal {
    @Override
    public void makeSound() {
        System.out.println("Cat meows.");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal dog = new Dog();
        dog.makeSound(); // Output: Dog barks.
        
        Animal cat = new Cat();
        cat.makeSound(); // Output: Cat meows.
    }
}

  

4、抽象類可以直接例項化嗎?

抽象類不能被直接例項化(不可以 Animal dog =new Animal()),在上面的示例中,抽象類 Animal 不能直接被例項化,但是可以建立其子類 DogCat 的例項來使用:

Animal dog = new Dog("Buddy");
Animal cat = new Cat("Whiskers");

  

5、說一個使用抽象類實現的設計模式?

模板方法模式,程式碼如下:

// 步驟 1:建立一個抽象類,定義演算法的骨架。
abstract class Beverage {

    // 模板方法,定義了演算法的骨架
    public final void prepareBeverage() {
        boilWater();
        brew();
        pourInCup();
        if (customerWantsCondiments()) {
            addCondiments();
        }
    }

    // 具體步驟由子類實現
    abstract void brew();

    abstract void addCondiments();

    // 公共步驟,已經實現
    void boilWater() {
        System.out.println("Boiling water");
    }

    void pourInCup() {
        System.out.println("Pouring into cup");
    }

    // 鉤子方法,子類可以覆蓋它以提供特定實現
    boolean customerWantsCondiments() {
        return true;
    }
}

// 步驟 2:建立具體子類,實現抽象類中的抽象方法。
class Coffee extends Beverage {

    @Override
    void brew() {
        System.out.println("Dripping Coffee through filter");
    }

    @Override
    void addCondiments() {
        System.out.println("Adding Sugar and Milk");
    }

    // 透過重寫鉤子方法,可以選擇不新增調料
    @Override
    boolean customerWantsCondiments() {
        // 重寫鉤子方法,這裡返回false表示不新增調料
        return false;
    }
}

class Tea extends Beverage {

    @Override
    void brew() {
        System.out.println("Steeping the tea");
    }

    @Override
    void addCondiments() {
        System.out.println("Adding Lemon");
    }
}

// 步驟 3:使用模板方法建立物件並呼叫其方法。
public class TemplatePatternDemo {

    public static void main(String[] args) {
        Beverage coffee = new Coffee();
        System.out.println("Making coffee...");
        coffee.prepareBeverage();

        System.out.println("\n");

        Beverage tea = new Tea();
        System.out.println("Making tea...");
        tea.prepareBeverage();
    }
}

  

6、說一個使用介面實現的設計模式?

策略模式,程式碼如下:

// 步驟 1:建立一個介面,定義演算法的統一介面。
interface DiscountStrategy {
    double applyDiscount(double originalPrice);
}

// 步驟 2:建立具體策略類,實現介面中定義的演算法。
class ChristmasDiscountStrategy implements DiscountStrategy {
    @Override
    public double applyDiscount(double originalPrice) {
        return originalPrice * 0.8; // 聖誕節打八折
    }
}

class BlackFridayDiscountStrategy implements DiscountStrategy {
    @Override
    public double applyDiscount(double originalPrice) {
        return originalPrice * 0.7; // 黑色星期五打七折
    }
}

// 步驟 3:建立使用策略的客戶類。
class ShoppingCart {
    private DiscountStrategy discountStrategy;

    public ShoppingCart(DiscountStrategy discountStrategy) {
        this.discountStrategy = discountStrategy;
    }

    public double checkout(double totalPrice) {
        // 應用促銷策略
        double finalPrice = discountStrategy.applyDiscount(totalPrice);
        System.out.println("Final price after discount: " + finalPrice);
        return finalPrice;
    }
}

// 步驟 4:使用策略模式進行測試。
public class StrategyPatternDemo {
    public static void main(String[] args) {
        // 聖誕節促銷
        ShoppingCart christmasCart = new ShoppingCart(new ChristmasDiscountStrategy());
        christmasCart.checkout(100); // 應付 80

        System.out.println();

        // 黑色星期五促銷
        ShoppingCart blackFridayCart = new ShoppingCart(new BlackFridayDiscountStrategy());
        blackFridayCart.checkout(100); // 應付 70
    }
}

  

相關文章