Java: substitution de variable statique de la classe parent?
J'ai la classe suivante qui je suis en utilisant comme base de tous les modèles de mon projet:
public abstract class BaseModel
{
static String table;
static String idField = "id";
public static boolean exists(long id) throws Exception
{
Db db = Util.getDb();
Query q = db.query();
q.select( idField ).whereLong(idField, id).limit(1).get(table);
return q.hasResults();
}
//snip..
}
Je suis alors en train de s'étendre à partir d'elle, de la manière suivante:
public class User extends BaseModel
{
static String table = "user";
//snip
}
Cependant, si j'essaie de faire ce qui suit:
if ( User.exists( 4 ) )
//do something
Alors, plutôt que de la requête: "SELECT id FROM user WHERE id = ?"
, c'est la production de la requête: "SELECT id from null where id = ?". Ainsi, la surcharge de la table
champ dans la User
classe ne semble pas avoir le moindre effet.
Comment puis-je surmonter cela? Si j'ai ajouté un setTable()
méthode pour BaseModel, et a appelé setTable()
dans le constructeur de User
, alors la nouvelle valeur de table
être disponible pour toutes les méthodes de la User
classe?
OriginalL'auteur Click Upvote | 2013-10-18
Vous devez vous connecter pour publier un commentaire.
Vous ne pouvez pas remplacer les méthodes statiques ou des champs de type Java.
Cela crée un nouveau champ
User#table
qui arrive juste à avoir le même nom queBaseModel#table
. La plupart des IDEs va vous en avertir.Si vous modifiez la valeur du champ dans BaseModel, il s'appliquera à toutes les autres classes du modèle.
Une façon est d'avoir la base de méthodes génériques
et de l'utiliser dans la sous-classe
Si vous souhaitez utiliser le champ de l'approche, vous devez créer un
BaseDAO
classe et ont unUserDAO
(un pour chaque classe du modèle) qui définit le champ en conséquence. Ensuite, vous créez singleton cas de tous les daos.J'ai étendu ma réponse.
exists()
n'est qu'un exemple ,j'ai une autre 10-20 ces méthodes d'aide. Je ne veux pas surcharger le tout, je préfère tout simplement de changer le nom de la table de la propriété de sorte qu'ils fonctionnent tous.C'est totalement un comportement attendu. C'est juste que l'OP n'a pas attendu à cela. L'OP est en train de parler sur la substitution des champs, qui n'est jamais fait. Pas même le champ d'instance.
"L'OP n'a pas prévu que" si c'était inattendu 😉 ... aussi, qui downvoted ma réponse? De donner au moins une raison quelconque, lâche!
OriginalL'auteur Cephalopod
Parce que Java ne permet pas de remplacer
static
membres, vous avez essentiellement besoin de recourir à un peu plus détaillé mais dans l'ensemble plus agréable le pattern singleton, où vous êtes toujours sur le plan conceptuel écrit "statique" du code, mais vous êtes techniquement à l'aide de (global/singleton/"statique") des cas, si vous n'êtes pas restreint par les limites de lastatic
.(notez que vous avez également besoin d'utiliser des méthodes parce que les champs ne participeront pas à la polymorphisme, et donc ne peut pas être remplacée)
Sorties:
OriginalL'auteur Erik Allik
Afin de faire ce que vous voulez faire, ne pas faire
table
statique dans leBaseModel
. Puis dans les autres classes qui héritent deBaseModel
, vous pouvez définirtable
dans le constructeur par défaut de ce que vous voulez.User.exists()
comme une méthode statique.cela pourrait être une indication que vous êtes un mauvais usage du
static
mot-clé. Je vous recommande de prendre un coup d'oeil à votre conception et retravailler pour se débarrasser de la nécessité d'unestatic
existe() la méthodeQuel est le problème avec mon design? Ce sera plus clair si j'ai fait une instance de mon modèle d'utilisateur juste pour vérifier si le nom d'utilisateur est valide?
Ne pas dire, il est quelque chose de mal avec votre conception, mais seulement qu'il peut être quelque chose que vous devez regarder si vous utilisez quelque chose comme ça où la conception du langage Java ne permet pas de faire ce que vous êtes désireux de le faire
vous pourriez si vous faites l'Utilisateur par défaut du constructeur statique. Je ne comprend pas que dans mon exemple (honte sur moi) parce que je pensais que vous voyez c'est la seule façon qu'il fonctionne avec votre application actuelle.
OriginalL'auteur Brian Dishaw