Java: How to create a public class that can be subclassed within package, while preventing outsiders from inheriting?


Java: How to create a public class that can be subclassed within package, while preventing outsiders from inheriting?



Suppose I am writing a package. I have the following inheritance hierarchy, all within my package:


public class Container {
public void size() {
System.out.println(10);
}
}

public final class Bucket extends Container {}

public final class Bag extends Container {}

public class Item {
Container container; // is aware of what container it's in. Will be initialized on construction.
public Container getContainer() {
return container;
}
}



I want to prevent others from subclassing Container. But I can't make it final because Bucket and Bag are subclasses. And I have to make it public or else outsiders cannot call getContainer(). Is there a way to do this in Java? Otherwise, what do people do in this type of situation?


Container


final


Bucket


Bag


public


getContainer()





So to clarify what you may be asking.... you want a class called Container that has two, and ONLY two, subclasses called Bucket and Bag, right?
– Ray Toal
Jul 2 at 1:46


Container


Bucket


Bag





Yes. I just realized that the closest thing I can think of to preventing it from being subclassed outside is to make Container's constructors package-private. Does that sound reasonable?
– bhh1988
Jul 2 at 1:48


Container





Sounds quite reasonable indeed.
– Ray Toal
Jul 2 at 1:49




1 Answer
1



To prevent a class from being subclassed by classes in other packages, make all the constructors package-private.



If the class doesn't have any constructors, it has the implicit default constructor, which is public, so you need to explicitly create a package-private no-arg constructor.


package foo;
public class Container {
Container () {/*package-private*/}
public void size() { System.out.println(10); }
}


package foo;
public final class Bucket extends Container {}


package bar;
public final class Oops extends Container {}



Compile Error: Implicit super constructor Container() is not visible for default constructor. Must define an explicit constructor


public final class Oops extends Container {
public Oops() {}
}



Compile Error: Implicit super constructor Container() is not visible. Must explicitly invoke another constructor



Of course, there are no other constructors, so it cannot be done.






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

JMeter fails on beanshell imports

Why in node-red my HTTP POST no receive payload from inject?

PHP contact form sending but not receiving emails