2010-06-18 2 views
1

Je suis en train d'écrire un projet sur Google App Engine, dans lequel j'ai un certain nombre de classes abstraites que j'espère pouvoir utiliser dans mes futurs projets et un certain nombre de classes concrètes en héritant. Parmi les autres classes abstraites, j'ai une servlet abstraite qui gère les utilisateurs, et j'ai un utilisateur abstrait. AbstractUser possède tous les champs et méthodes nécessaires pour le stocker dans le magasin de données et indiquer si l'utilisateur est enregistré avec mon service ou non. Il n'implémente aucune fonctionnalité spécifique au projet. La servlet abstraite qui gère les utilisateurs fait uniquement référence aux méthodes déclarées dans la classe AbstractUser, ce qui lui permet de générer des liens pour se connecter, se déconnecter et s'enregistrer (pour les utilisateurs non enregistrés). Afin de mettre en œuvre la fonctionnalité utilisateur spécifique au projet, j'ai besoin de sous-classer l'utilisateur abstrait. Les servlets que j'utilise dans mon projet sont tous des descendants indirects de cette servlet de gestion d'utilisateur abstraite, et l'utilisateur est un champ protégé, donc les servlets descendants peuvent l'utiliser comme leur propre champ. Cependant, chaque fois que je veux accéder à une méthode spécifique au projet de l'utilisateur concret, j'ai besoin de le convertir en ce type. -à-direDéfinition du type d'un champ dans une superclasse à partir d'une sous-classe (Java)

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


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

tout autre servlet du projet:

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

Eh bien, ce que je voudrais faire est de faire en quelque sorte le type de « utilisateur » dans les superclasse dépendent de quelque chose dans le projet -spécifique classe abstraite. Est-ce possible?

Et je ne veux pas bouger tous les trucs de gestion des utilisateurs dans une couche spécifique au projet, car je voudrais avoir pour mes futurs projets déjà écrits :)

Merci pour votre aide.

Répondre

3

Faites votre AbstractServlet générique:

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

Vous pouvez alors faire les implémentations utilisent une sous-classe spécifique de AbstractUser:

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

Ensuite, vous ne aurez plus besoin de jeter, comme tout lieu que vous avez T dans la classe de base, votre implémentation se référera maintenant à ConcreteUser:

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

Merci beaucoup, cela a fonctionné parfaitement. – Ibolit

0

Je pense que ce dont vous avez besoin est classe générique:

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(); 
    } 
} 
Questions connexes