禁止在其包之外直接扩展 Java 类

发布于 2024-07-16 20:23:14 字数 467 浏览 7 评论 0原文

我有一个带有 a 的包,

public abstract class Player { /*...*/ }

并且该包的这些

public abstract class GamePlayer extends Player { /*...*/ }
public abstract class TournamentPlayer extends Player { /*...*/ }
public abstract class StatelessPlayer extends Player { /*...*/ }

用户需要 Player,但为了在不破坏它的情况下使用该包,我要求他们从不直接扩展 Player。 相反,他们应该扩展所提供的子类之一。

问:如何防止用户直接扩展Player?

我正在寻找一种方法来明确这一禁令的意图。

I have a package with a

public abstract class Player { /*...*/ }

and these

public abstract class GamePlayer extends Player { /*...*/ }
public abstract class TournamentPlayer extends Player { /*...*/ }
public abstract class StatelessPlayer extends Player { /*...*/ }

Users of the package need Players but in order to use the package without breaking it I require that they never directly extend Player. Instead they should extend one of the subclasses provided.

Question: How should I prevent users from extending Player directly?

I'm looking for a way that makes it obvious that this prohibition is intended.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

听不够的曲调 2024-07-23 20:23:14

使 Player 中的构造函数仅具有包访问权限。 然后他们将无法调用构造函数或自行扩展它。 如果您在 Player 中还没有显式构造函数,请创建一个(否则编译器将创建一个默认的公共无参数构造函数)。

(请注意,我只建议对构造函数执行此操作。类本身可以是公共的,以便客户端仍然可以使用它。)

这之所以有效,是因为任何构造函数(除了 java.util.constructor 中的构造函数除外)。 lang.Object)必须调用超类构造函数(显式或隐式)。 如果没有可访问的构造函数,则无法创建子类。

Make the constructors in Player have package access only. Then they won't be able to call the constructor or extend it themselves. If you don't already have an explicit constructor in Player, create one (as otherwise the compiler will create a default public parameterless constructor).

(Note that I've only suggested doing this to the constructor. The class itself can be public so that clients can still use it.)

This works because any constructor (other than in java.lang.Object) has to call a superclass constructor (either explicitly or implicitly). If there are no accessible constructors, you can't create the subclass.

毅然前行 2024-07-23 20:23:14

确保 Player 的构造函数不是公共的:

public abstract class Player {
    Player() {
        // initialization goes here
    }
}

然后类可以从同一包内扩展 Player,但不能从包外部扩展。

Make sure the constructors of Player are not public:

public abstract class Player {
    Player() {
        // initialization goes here
    }
}

Then classes can extend Player from within the same package, but should not be able to from outside of the package.

鲜血染红嫁衣 2024-07-23 20:23:14

嗯...让 Player 类成为非公开的? 只要省略“public”,那么它将是包私有的,即只有同一包中的类可以扩展它。

然而,没有什么可以完全阻止人们将自己的类放入该包中。 我相信可以通过将其放入签名的 JAR 中来阻止它,然后任何在同一包中加载未签名(或不同签名)的类的尝试都会失败。

Um... make the Player class non-public? Just leave out "public", then it will be package-private, i.e. only classes in the same package can extend it.

However, nothing outright prevents people from putting their own classes in that package. I believe it's possible to prevent it by putting it into a signed JAR, then any attempt to load an unsigned (or differently-signed) class in the same package will fail.

世俗缘 2024-07-23 20:23:14

使用默认访问修饰符,也称为“包私有”访问。 换句话说,不要指定访问修饰符

abstract class Player { /*...*/ }

此处的文档Sun 网站 更详细地描述了所有访问修饰符。

Use the default access modifier, also known as "Package private" access. In other words, don't specify an access modifier

abstract class Player { /*...*/ }

The documentation here at Sun's website describes all of the access modifiers in greater detail.

幸福%小乖 2024-07-23 20:23:14

我建议为

  • 您希望客户端访问的内容创建公共接口,但不创建或子类
  • 为您希望客户端访问的内容创建公共类并且创建或子类
  • 其他任何内容都应该是非公共的

问题这种方法的缺点是,您最终需要将所有内容都放在一个包中,随着库的增长,这对组织来说是不利的。

要允许使用多个受保护的包,请查看 OSGi。

OSGi 允许您限制捆绑包 (jar) 允许其他捆绑包访问哪些包,甚至可以设置允许额外可见性的“朋友”捆绑包。

当您确实想要保护变得很大的库时,Java 的包作为保护单元模型是不够的......

I'd recommend

  • Create public interfaces for things you want clients to access but not create or subclass
  • Create public classes for things you want clients to access and create or subclass
  • anything else should be non-public

The problem with this approach is that you end up with everything needing to be in a single package, which is bad for organization as the library grows.

To allow use of multiple packages with protection, take a look at OSGi.

OSGi allows you to restrict which packages a bundle (jar) allows other bundles to access, and even set up "friend" bundles that are allowed extra visibility.

Java's package-as-protection-unit model is not sufficient when you really want to protect libraries that get large...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文