7

我有一个包裹

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?

我正在寻找一种方法来明确表明该禁令是有意的。

4

5 回答 5

20

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

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

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

于 2009-04-08T13:23:37.233 回答
9

确保 Player 的构造函数不公开:

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

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

于 2009-04-08T13:24:28.603 回答
0

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

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

于 2009-04-08T13:25:35.340 回答
0

我会推荐

  • 为您希望客户端访问但不创建或子类的事物创建公共接口
  • 为您希望客户访问创建或子类化的事物创建公共类
  • 其他任何事情都应该是非公开的

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

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

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

当您真的想保护变得很大的库时,Java 的包即保护单元模型是不够的......

于 2009-04-08T15:06:02.883 回答
-1

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

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

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

于 2009-04-08T13:23:08.997 回答