【问题标题】:Setting the type of a field in a superclass from a subclass (Java)从子类(Java)设置超类中字段的类型
【发布时间】:2010-06-18 11:13:47
【问题描述】:

我正在 Google App Engine 上编写一个项目,其中我有许多抽象类,我希望能够在我未来的项目中使用它们,以及一些从它们继承的具体类。 在其他抽象类中,我有一个执行用户管理的抽象 servlet,并且我有一个抽象用户。 AbstractUser 具有所有必要的字段和方法,用于将其存储在数据存储中并告知用户是否注册了我的服务。它不实现任何项目特定的功能。管理用户的抽象 servlet 仅引用 AbstractUser 类中声明的方法,它允许它生成用于登录、注销和注册(针对未注册用户)的链接。 为了实现特定于项目的用户功能,我需要对 Abstract 用户进行子类化。我在项目中使用的servlet都是那个抽象的用户管理servlet的间接后代,而用户是其中的受保护字段,所以后代servlet可以将其用作自己的字段。但是,每当我想访问具体用户的任何项目特定方法时,我都需要将其转换为该类型。 即

(abstract user managing servlet)
...
AbstractUser user = getUser();
...
abstract protected AbstractUser getUser();


(project-specific abstract servlet)
@Override
protected AbstractUser getUser() {
   return MyUserFactory.getUser();
}

任何其他项目特定的 servlet:

int a = ((ConcreteUser) user).getA();

好吧,我想做的是以某种方式使超类中的“用户”类型依赖于项目特定抽象类中的某些内容。有可能吗?

而且我不想将所有用户管理的东西移到一个项目特定的层,因为我希望在我未来的项目中已经编写好它:)

感谢您的帮助。

【问题讨论】:

    标签: java design-patterns inheritance


    【解决方案1】:

    使您的AbstractServlet 通用:

    public class AbstractServlet<T extends AbstractUser> { 
        private T user;
        protected abstract T getUser();
        ...
    

    然后你可以让实现使用AbstractUser的特定子类:

    public class ConcreteServlet extends AbstractServlet<ConcreteUser> { ...
    

    然后您将不再需要转换,因为您在基类中有T 的任何地方,您的实现现在将引用ConcreteUser

    @Override
    protected abstract ConcreteUser getUser() { .. }
    

    【讨论】:

      【解决方案2】:

      我认为你需要的是泛型类:

      class AbstractUserManager<UserType extends AbstractUser> {
          protected UserType user;    
      
          public UserType getUser() {
              return user;
          }
      
          public void addUser(UserType u) {
              this.user = u; 
          }
      
          ...some other methods that use AbstractUser and dont need specific functionality...
      }
      
      //Class used for managing AbstractUsers with no extra features
      class SimpleUserManager extends AbstractUserManager<AbstractUser> {
      //No body as AbstractUserManager is enough
      }
      
      //Class that manages CrazyUsers
      class CrazyUserManager extends AbstractUserManager<CrazyUser> {
          public CrazyUserManager() {
              this.setUser(new CrazyUser());
          }
      
          public someNewFunction() {
              this.getUser().someCrazyActionOnlyCrazyUsersHave();
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-08
        • 1970-01-01
        • 2011-01-31
        • 2019-07-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多