在Java中将子类的创建限制为其父(或其他)类

时间:2015-09-06 04:03:11

标签: java

我有一个超类GameObject,它是游戏中所有对象的超类型。 我希望将所有创建和管理代码包含在其中的静态方法中;它应该是唯一能够使其他对象扩展GameObject的类。 有时候我需要创建一个新对象,有时候我会列出一些我出于性能原因选择的对象列表。

有没有办法限制孩子的构造函数访问它的基类,或者设计模式来做我想做的事情?

3 个答案:

答案 0 :(得分:1)

1)制作超类摘要

2)编写一个工厂方法,从超类类型创建子类。

由于Base类(超类)是抽象的,因此子类始终是基类类型。

您可以在FactoryMethod中避免条件。请参阅我的帖子@ Inheritance-aware class to value map to replace series of `instanceof`

e.g。

$myarray = array('tbl1','tbl2','tbl3','tbl4');
// get random value from array
$key = array_rand($myarray);
$table= $myarray[$key];

答案 1 :(得分:1)

使用Java的访问修饰符,您有两种方法:

  1. 将父类中的所有子类封装为private static嵌套类:

    public abstract class GameObject {
        private GameObject() {
        }
    
        private static class GameObjectImpl1 extends GameObject {
        }
    }
    
  2. 由于父类的构造函数是私有的,因此无法将其扩展到外部。此外,它不可能实例化GameObject,因为它是抽象的。

    这种方法的唯一缺点是你需要将所有子类完全放在父类中,即文件很大。

    1. 您可以为您的基类及其所有孩子创建单独的专用包。使基类(GameObject)成为此包中唯一的公共类。使它的构造函数包私有(同一个包中的子类仍然可以访问它)。

      package game;
      
      public abstract class GameObject {
          GameObject() { //package-private
          }
      
          public static GameObject create() {
              return new GameObjectImpl1();
          }
      }
      
       //---------------
      package game;
      
      class GameObjectImpl1 extends GameObject { //package-private
      }
      
    2. 这种方法的一个小缺点是它可以被黑客攻击"通过在其他源根目录中创建具有相同名称的包。这些类可以访问game包中的包私有类。但是,否则这是最干净的方法,我建议接受它。

答案 2 :(得分:0)

我知道有两种方法可能不止于此。

  1. 将基类声明为最终版。
  2. Make Base类的构造函数是私有的。