3

I have a superclass GameObject that's a supertype of all objects in the game. I want to contain all the creation and management code as static methods inside it; it should be the only class able to make other objects that extend GameObject. Sometimes I'll need to create a new object, other times I'll have a list of objects I'll pick from for performance reasons.

Is there a way to restrict access of a child's constructor to its base class, or a design pattern to do what I want?

Stephen Davis
  • 31
  • 1
  • 3

3 Answers3

1

1) Make the super class Abstract

2) Write a factory method to create Child Class from super class type.

Since Base class ( Super class) is abstract, child class is always base class type.

You can avoid if condition in FactoryMethod. Refer to my post @ Inheritance-aware class to value map to replace series of `instanceof`

e.g.

SuperClass object = (SuperClass) Class.forName(specificClassName).newInstance();
Community
  • 1
  • 1
Ravindra babu
  • 37,698
  • 11
  • 250
  • 211
1

Using Java's access modifiers you have two approach:

  1. Encapsulate all child classes inside the parent class as private static nested classes:

    public abstract class GameObject {
        private GameObject() {
        }
    
        private static class GameObjectImpl1 extends GameObject {
        }
    }
    

As constructor of the parent class is private it's not possible to extend it outside. Also it's not possible to instantiate GameObject, as it is abstract.

The only downside of this approach is that you need to put all child classes literally inside the parent, i.e. the file gonna be large.

  1. You can create separate dedicated package for your base class and all it's children. Make the base class (GameObject) the only public class in this package. Make it's constructor package-private (child classes in the same package will still have access to it).

    package game;
    
    public abstract class GameObject {
        GameObject() { //package-private
        }
    
        public static GameObject create() {
            return new GameObjectImpl1();
        }
    }
    
     //---------------
    package game;
    
    class GameObjectImpl1 extends GameObject { //package-private
    }
    

The minor downside of this approach is that it can be "hacked" by creating package with the same name in other source root. Classes there will have access to your package-private classes inside the game package. However, otherwise this is the most clean approach and I'd recommend taking it.

Aivean
  • 10,692
  • 25
  • 39
0

There are two approaches i know there may be more than this.

  1. Declared Base class as Final.
  2. Make Constructor of Base class is private.
François Maturel
  • 5,884
  • 6
  • 45
  • 50