【Java面试题-基础知识02】Java抽象类和接口六连问?

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 不能直接被实例化,但是可以创建其子类 Dog 和 Cat 的实例来使用:

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
    }
}

  

  • 11
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值