views:

106

answers:

3

Sorry the question wasn't properly stated by me earlier. I try to implent the Factory Pattern. A better example: It is an abstract class Human with a function create. Based on the arguments that is passed to create it decides whether to return an instance of its subclass Man or an instance of subclass Woman. So you call create with: Human john = Human.create("Man"); The subclasses Man and Woman are inherited from the abstract class Human and are defined in the same file as Human. I don't want it to be possible to extend it by: Human lisa = new Human("woman") {}; From the main program. Thanks!

EDIT:

Thanks for all the help! The solution I finally used was to let the class Human be public, as well as its function create. The Human constructor and the Man and Woman classes are declared "package-protected".

+1  A: 

Don't use a visibility specifier in the class declaration for A and it will be a package access class.

Edit to reflect change in question:

Option 1: Make the constructors for Human package private. By doing this, any class which attempts to extend Human outside of the package will fail because it can not call a constructor of the super class.

Option 2: Stick with my original suggestion of a package private class and use instead a public access factory class.

Tim Bender
Sorry the question was properly stated by me. I try to implent the Factory Pattern. A better example: It is an abstract class Human with a function create. Based on the arguments that is passed to create it decides whether to return an instance of its subclass Man or an instance of subclass Woman. So you call create with: Human john = Human.create("Man"); The subclasses Man and Woman are inherited from the abstract class Human and are defined in the same file as Human. I don't want it to be possible to extend it by:Human lisa = new Human("woman") {};From the main program. Thanks!
Ad
Sorry again it should say "NOT properly stated"... :-)
Ad
You should edit your question to reflect what you say here rather than just reply to the comment.
DJClayworth
My mistake, I've edited the original question
Ad
A: 

It depends what you mean by not possible. If you want it statically enforced, the only way to do that is to make the class package access, but that doesn't specifically limit anonymous classes - it limits named classes as well. If you want to enforce it at runtime, you can do this in the constructor of the abstract class

 if (this.getClass().isAnonymousClass() && !this.getClass().getName().startsWith(packageName)) {
     throw new IllegalStateException("This class cannot be used as an anonymous inner class");
  }
Yishai
My question was badly stated, really sorry to waste your time due to that. But if you read the comment I replied to the first answer I hope I managed to describe my problem I a better way. This was a real cool way to do it though. Cheers!
Ad
This solution works great, thanks. I only needs to use the "if (this.getClass().isAnonymousClass())" part to achieve what i was looking for.
Ad
It would of course be nice to have an error at compile-time though.
Ad
A: 

Declare your class as final

A final class cannot be subclassed. This is done for reasons of security and efficiency. Accordingly, many of the Java standard library classes are final, for example java.lang.System and java.lang.String. All methods in a final class are implicitly final.

Romain Hippeau
I cannot declare it as final since the two classes man and Woman are inherited from Human,
Ad
You declare each one as final:final class Man {}final class Woman {}
Romain Hippeau