面试题答案
一键面试1. protected 和 default 修饰符对程序架构的影响
- protected:
- 可维护性:protected 修饰的成员可以被同一包内的类以及不同包中的子类访问。这在一定程度上增加了代码的耦合度,因为子类对父类 protected 成员的访问可能会导致父类实现细节暴露。当父类的 protected 成员发生变化时,可能影响到多个子类,维护成本增加。
- 扩展性:从扩展性角度看,protected 成员为子类提供了一定的扩展能力,子类可以基于这些 protected 成员进行功能扩展。但过度使用可能导致子类与父类之间的关系过于紧密,不利于系统的灵活扩展。
- default(即包访问权限,没有修饰符时的默认情况):
- 可维护性:default 修饰的成员只能被同一包内的类访问。这在一定程度上限制了访问范围,使得包内的类之间形成相对紧密的联系。如果包结构设计不合理,包内类对 default 成员的依赖可能导致维护困难,因为对一个类的修改可能影响到包内其他依赖它的类。
- 扩展性:对于扩展性而言,default 修饰符限制了外部包对该类成员的访问,有利于保持包的独立性。但如果需要在不同包之间进行功能扩展,可能需要重新设计包结构或使用其他方式来暴露功能。
2. 优化策略
- 减少 protected 使用:
- 策略:将部分 protected 成员提升为 public 并通过接口来暴露,使得子类可以通过接口来访问相关功能,减少对子类直接访问父类实现细节的依赖。同时,对于一些只在子类内部使用的逻辑,可以提取到一个单独的方法,并通过 protected 方法调用,这样父类的核心逻辑与子类扩展逻辑进一步分离。
- 示例代码:
// 定义一个接口
interface CommonFunction {
void commonOperation();
}
// 父类实现接口
class ParentClass implements CommonFunction {
private int data;
// 原本的 protected 方法
// 现在通过接口方法暴露给外部
@Override
public void commonOperation() {
// 具体实现
}
// 提取只在子类内部使用的逻辑
protected void internalSubclassLogic() {
// 具体逻辑
}
}
// 子类继承父类
class SubClass extends ParentClass {
@Override
public void commonOperation() {
super.commonOperation();
internalSubclassLogic();
}
}
- 优化 default 使用:
- 策略:如果不同包需要访问 default 修饰的功能,可以考虑将相关功能封装成一个服务类,并通过合适的设计模式(如工厂模式、单例模式)来提供访问入口。这样既可以保持包的相对独立性,又能在需要时为外部包提供访问途径。
- 示例代码:
// 原本包内有一个具有 default 访问权限的类
class PackageInternalClass {
void internalFunction() {
// 具体功能
}
}
// 定义一个服务类,使用单例模式
class PackageService {
private static PackageService instance;
private PackageInternalClass internalClass;
private PackageService() {
internalClass = new PackageInternalClass();
}
public static PackageService getInstance() {
if (instance == null) {
instance = new PackageService();
}
return instance;
}
public void performInternalFunction() {
internalClass.internalFunction();
}
}
在其他包中,可以通过以下方式访问:
// 其他包中的类
class OtherPackageClass {
public void usePackageService() {
PackageService.getInstance().performInternalFunction();
}
}