gpt4 book ai didi

java - 防止子类添加方法

转载 作者:搜寻专家 更新时间:2023-10-31 08:20:15 24 4
gpt4 key购买 nike

这似乎是一件奇怪的事情,但是在 Java 中有没有一种方法可以阻止子类添加新方法(包括构造函数),同时仍然允许子类覆盖方法?

实际情况是我们有一个带有一些抽象方法和构造函数的抽象

abstract class A {
abstract A doX();
abstract boolean isY();
public A(String s){ ... };
}

我们希望这个类的所有具体子类只覆盖这些方法和构造函数。

这是关于在我们的代码中强制执行某种风格,即阻止其他人在代码上添加东西。我们可以直接告诉他们不要这样做,但这很少奏效,所以我们想知道是否有实现这一目标的编程方法。

显然该类不能是final。效率不是最重要的 - 更简洁的代码更为重要。

更新 - 动态方法

正如答案中所指出的,没有办法静态地执行此操作,因为防止创建子类的唯一方法是使用 final,这是行不通的。但我可以使用动态方法,所以我目前的解决方案是将这个 aspect 添加到项目(它已经使用了 AspectJ)。

   public aspect WatchA{
before() : execute(* A.*()) || execute(* A.*(..)) {
String methodCalled = joinPoint.getSignature().getName();
Class<?> c = Class.forName(args[0])
Method[] allMethods = c.getDeclaredMethods();
boolean found = false;
for(Method m : allMethods)
found |= m.getName().equals(methodCalled);
if(!found)
throw new RuntimeException("Do not add method "+methodCalled+" to A");
}
}

如果他们使用这些新方法中的任何一种,都会导致他们的测试失败。

最佳答案

你不能那样做。只有当类是 final 时,您才能确保不能创建子类。

您还可以将方法设为最终的(即使在抽象类中),这样就禁止覆盖它们。

最好的办法是创建一个接口(interface),让所有方法都可见,并强制 API 的所有用户通过该接口(interface)访问对象。这样,即使实现添加了自己的东西,所说的东西也不会可见。

一个解决方案是实现一个工厂来返回具体类;为了“增加安全性”,您可以将所有实现放在与该工厂相同的包中,并将构造函数包放在本地(但这通常不切实际):

public final class MyFactory
{
// ....
public MyInterface getConcrete()
{
return new MyInterfaceImpl();
}
// etc etc -- getStones(), getTar(), getFeathers() and so on
}

请注意,构建器也可用于此目的。

关于java - 防止子类添加方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17146686/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com