Search code examples
javainheritancesubclassaccess-modifiers

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?


Solution

  • 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.