面试题答案
一键面试1. Java抽象类和具体类基础概念
- 抽象类:包含抽象方法(仅有方法声明,无方法体)的类,必须被
abstract
关键字修饰。抽象类不能被实例化,主要用于定义一些通用的行为和属性,为子类提供一个通用的框架。 - 具体类:没有抽象方法的普通类,可以被实例化,用于实现具体的业务逻辑。
2. 策略模式中抽象类和具体类的角色
策略模式设计理念
定义一系列算法,将每个算法封装起来,并使它们可以相互替换。策略模式让算法的变化独立于使用算法的客户。
代码示例
// 抽象策略类(抽象类扮演定义通用行为接口的角色)
abstract class Strategy {
abstract void execute();
}
// 具体策略类A(具体类实现具体的算法逻辑)
class ConcreteStrategyA extends Strategy {
@Override
void execute() {
System.out.println("执行策略A");
}
}
// 具体策略类B(具体类实现具体的算法逻辑)
class ConcreteStrategyB extends Strategy {
@Override
void execute() {
System.out.println("执行策略B");
}
}
// 上下文类,使用策略
class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
void executeStrategy() {
strategy.execute();
}
}
在策略模式中,抽象类Strategy
定义了所有具体策略的通用接口execute
,具体类ConcreteStrategyA
和ConcreteStrategyB
实现了该接口,提供具体的算法实现。客户端通过Context
类来选择并执行不同的策略。
3. 模板方法模式中抽象类和具体类的角色
模板方法模式设计理念
定义一个操作中的算法骨架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
代码示例
// 抽象模板类(抽象类定义算法骨架)
abstract class AbstractTemplate {
// 模板方法,定义算法骨架
final void templateMethod() {
step1();
step2();
step3();
}
// 具体子类必须实现的抽象方法
abstract void step1();
// 具体子类可以重写的方法
void step2() {
System.out.println("默认的step2实现");
}
// 具体子类必须实现的抽象方法
abstract void step3();
}
// 具体模板类(具体类实现抽象类定义的抽象方法)
class ConcreteTemplate extends AbstractTemplate {
@Override
void step1() {
System.out.println("ConcreteTemplate的step1实现");
}
@Override
void step3() {
System.out.println("ConcreteTemplate的step3实现");
}
}
在模板方法模式中,抽象类AbstractTemplate
定义了算法的骨架templateMethod
,其中包含了抽象方法step1
、step3
和可重写的方法step2
。具体类ConcreteTemplate
实现了抽象方法,完成具体的业务逻辑。
4. 如何选择抽象类还是具体类
- 从复用角度:如果多个类有一些共同的行为和属性,并且这些共同部分可以被提取出来,那么使用抽象类。例如在模板方法模式中,抽象类定义的算法骨架和一些通用方法可以被多个具体子类复用。
- 从灵活性角度:如果需要在运行时根据不同情况选择不同的行为,策略模式是一个很好的选择,此时抽象类定义通用接口,具体类实现不同的行为,便于动态替换。
- 从业务需求角度:如果业务逻辑已经明确且不需要变化,直接使用具体类实现即可。例如一些工具类,它们只提供特定的功能,不需要被继承和扩展,使用具体类就足够。
如果希望为一组相关的类提供一个通用的接口和实现框架,或者希望强制子类实现某些方法,抽象类是合适的选择。如果只是单纯实现具体的业务逻辑,没有复用或扩展的需求,具体类更为简单直接。