Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prohibit direct extension of Java class outside its package

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.

like image 533
jjujuma Avatar asked Apr 08 '09 13:04

jjujuma


2 Answers

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.

like image 119
Jon Skeet Avatar answered Nov 15 '22 20:11

Jon Skeet


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.

like image 35
Lee Avatar answered Nov 15 '22 18:11

Lee