获取子类的静态数据

时间:2013-03-23 02:45:27

标签: java class subclass

我有一个课程Player,需要获得Location课程。每个位置类都扩展Location,其中有一个返回静态实例的方法get()

如果角色的字符串引用了位置扩展类的名称,我该如何获取该实例?

字符:

public class Player {
    public static Location getLocation() {
        try {
            //return location
        } catch (Exception ex) {
            Logger.getLogger(Player.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }
}

位置:

public class Location{
    protected static Location singleton;
    public static Location get() {
        return null;
    }

位置等级:

public class Finleydale extends Location{
    public static Location get() {
        if (Finleydale.singleton == null) {
            Finleydale.singleton = new Finleydale();
        }
        return singleton;
    }
}

我有多个附加地址信息,并且我在位置类中有单例,因此所有附加地址信息都包含它;单例是静态的,因为该位置只有一个版本。 有人可以帮我这个吗?

3 个答案:

答案 0 :(得分:0)

在基类中声明静态字段的方式意味着整个程序中只有一个引用。如果您有多个子类,并且每个子类都分配给它,那么每个子类都将分配给 Location基类中的相同(静态)字段。我想你想在每个子类中有一个单独的单例。

如果你想按键查找一个特定的位置(比如一个字符串值),那么我认为Singleton模式并不是你想要的。我会创建一个“位置注册表”类,如下所示:

public class LocationRegistry
    {
    private static final Map<String, Location> registry;
    static
        {
        final Map<String, Location> _registry = new HashMap<>();
        _registry.put("Finleydale", new Finleydale());
        // ...
        registry = Collections.unmodifiablemap(_registry);
        }

    public static Location getLocation(final String id)
        {
        return registry.get(id);
        }
    }

一些注意事项:

  • 您仍然可以使用Singleton模式填充注册表
  • 如您的问题所示,经典的Singleton模式不是线程安全的。没有不必要的锁定的正确的线程安全版本是非常棘手的,如果不是不可能的话。 static final字段很好地解决了这个问题。
  • 没有必要让注册表显式引用每个Location子类。您可以让每个位置自行注册。唯一的诀窍是有一个机制可以加载位置,以便他们可以自己注册。
  • 子类实际上是否适合此用途?不同的位置有不同的行为或只是不同的数据(即名称)?如果是后者,那么我只使用一个Location类和一个工厂(例如上面的静态初始化程序)来创建每个位置。

答案 1 :(得分:0)

关于你的对象模型的东西似乎是错误的。为什么没有一个带有Locatable方法的接口getLocation(),接口的实现者可以返回它们各自的位置。单身Location似乎在概念上是错误的。

interface Locatable { 
   Location getLocation();
}

class FinleyLand implements Locatable { 
    @Override
    Location getLocation() { 
       //whatever it takes to get you there...
    }     
}

答案 2 :(得分:0)

我取走了get()函数的静态修改器并更改了Player类,如图所示。
其他所有人,你的输入很棒。

    String locationS; //Class name
    public static Location getLocation() {
        return ((Location) Class.forName(locationS).newInstance()).get();
    }