Les variables abstraites en Java?

je viens de c# où c'était facile, et possible.

j'ai ce code:

public abstract class clsAbstractTable {

    public abstract String TAG;
    public abstract void init();

}

mais Eclipse me dit que j'utilise un modificateur illégal.

j'ai cette classe:

public class clsContactGroups extends clsAbstractTable {


}

je veux que la variable et la méthode soient définies de telle façon, que L'éclipse soit invite de moi, j'ai jamais été appliquée abstraite variables et méthodes.

Comment dois-je définir ma classe abstraite, donc je devrais être invité à mettre en œuvre les résumés?

EDIT 1

je vais créer différentes classes pour différentes tables de base de données. Chaque classe devrait avoir sa propre variable TABLENAME, aucune exception. Je dois m'assurer que cette variable est statique à chaque fois que je crée une nouvelle classe qui étend la classe abstraite.

alors dans la classe abstraite j'aurai une méthode eg: init ();

si dans cette méthode init() J'appelle TABLENAME, elle devrait prendre la valeur de sous-classe.

quelque chose comme cela devrait également travailler sur

String tablename=(clsAbstract)objItem.TABLENAME;
// where objItem can be any class that extended clsAbstract;

EDIT 2

je veux une constante(statique) définie dans chaque classe dont le nom est défini dans l'abstrait.

  • j'ai défini la variable TABLENAME dans l'abstrait, mais aucune valeur n'est donnée.
  • je crée un clsContactGroups, je devrais être invité à implémenter TABLENAME, c'est là que je reçois quelques données. eg: TABLENAME= "contactgroups";
  • je crée un deuxième classe clsContacts, je devrais être invité à implémenter TABLENAME, c'est là qu'on obtient quelques données. eg: TABLENAME= "contacts";

    etc...
41
demandé sur Bob 2010-03-03 15:10:09

10 réponses

je pense que votre confusion est avec C # properties vs. fields / variables. Dans C# vous ne pouvez pas définir des champs abstraits, même dans une classe abstraite. Vous pouvez, cependant, définir des propriétés abstraites car ce sont effectivement des méthodes (par exemple compilées à get_TAG() et set_TAG(...)).

comme certains l'ont rappelé, vous ne devriez jamais avoir de champs/variables publics dans vos classes, même en C#. Plusieurs réponses ont laissé entendre ce que je recommanderais, mais ne l'ont pas précisé. Vous devriez traduire votre idée en Java comme un JavaBean de la propriété, à l'aide de getTAG(). Alors vos sous-classes devront implémenter ceci (j'ai aussi écrit un projet avec des classes table qui font cela).

Donc vous pouvez avoir une classe abstraite définie comme ceci...

public abstract class AbstractTable {

    public abstract String getTag();
    public abstract void init();

    ...
}

ensuite, dans n'importe quelle sous-classe concrète vous devez définir une variable finale statique (constante) et retourner que de la getTag(), quelque chose comme ceci:

public class SalesTable extends AbstractTable {

    private static final String TABLE_NAME = "Sales";

    public String getTag() {
        return TABLE_NAME;
    }

    public void init() {
        ...
        String tableName = getTag();
        ...
    }

}

EDIT:

vous ne pouvez pas outrepasser champs hérités (en C# ou Java). Vous ne pouvez pas non plus outrepasser les membres statiques, qu'il s'agisse de champs ou de méthodes. Ce qui est la meilleure solution pour cela. J'ai changé mon exemple de méthode init ci - dessus pour montrer comment cela serait utilisé-encore une fois, pensez à la méthode getXXX comme une propriété.

45
répondu Kevin Brock 2010-03-03 12:56:16

Définir un constructeur dans la classe abstraite qui définit le champ des implémentations concrètes sont par la spécification requise pour appeler/surcharger le constructeur.

E. G.

public abstract class AbstractTable {
    protected String name;

    public AbstractTable(String name) {
        this.name = name;
    }
}

Lorsque vous étendez AbstractTable, la classe ne compilera pas tant que vous n'aurez pas ajouté un constructeur qui appelle super("somename").

public class ConcreteTable extends AbstractTable {
    private static final String NAME = "concreteTable";

    public ConcreteTable() {
        super(NAME);
    }
}

de cette façon, les implémenteurs sont tenus de définir name. De cette façon, vous pouvez aussi faire des vérifications (null)dans le constructeur de la classe abstraite pour faire il est plus robuste. E. g:

public AbstractTable(String name) {
    if (name == null) throw new NullPointerException("Name may not be null");
    this.name = name;
}
57
répondu BalusC 2010-03-03 13:48:44

pas de variables abstraites en Java (ou C++).

si la classe parent a une variable, et une classe enfant étend le parent, alors l'enfant n'a pas besoin d'implémenter la variable. Il a juste besoin d'accéder à l'instance du parent. Soit get / set ou l'accès protégé fera l'affaire.

"...je devrais donc être invité à mettre en œuvre les résumés"? Si vous prolongez une classe abstraite et que vous ne parvenez pas à implémenter une méthode abstraite, le compilateur vous dira d'implémenter l'une ou l'autre de ces méthodes. elle ou marquer la sous-classe en tant qu'abrégé. C'est tout à l'incitation que vous allez obtenir.

6
répondu duffymo 2010-03-03 12:14:31

il suffit d'ajouter cette méthode à la classe de base

public abstract class clsAbstractTable {

    public abstract String getTAG();
    public abstract void init();

}

Maintenant, chaque classe qui étend la classe de base (et ne veut pas être abstraite) devrait fournir une BALISE

Vous pouvez aussi aller avec BalusC réponse

2
répondu Lombo 2010-03-03 12:15:03

le mieux que vous puissiez faire est d'avoir des accesseurs/mutateurs pour la variable.

Quelque chose comme getTAG ()

De cette façon, toutes les classes aurait à mettre en œuvre.



les classes Abstraites sont utilisés pour définir des comportements abstraits, pas de données.

2
répondu Padmarag 2010-03-03 12:50:53

Comme il n'y a pas de mise en œuvre d'une variable, il ne peut pas être abstraite ;)

1
répondu Tomas Vana 2010-03-03 12:13:31

Pourquoi voulez-vous que toutes les sous-classes définissent la variable? Si chaque sous-classe est supposée l'avoir, il suffit de le définir dans la superclasse. BTW, étant donné que c'est une bonne pratique de ne pas exposer les champs de toute façon, votre question a encore moins de sens.

1
répondu Erich Kitzmueller 2010-03-03 12:17:10

Changer le code:

public abstract class clsAbstractTable {
  protected String TAG;
  public abstract void init();
}

public class clsContactGroups extends clsAbstractTable {
  public String doSomething() {
    return TAG + "<something else>";
  }
}

de Cette façon, toutes les classes qui héritent de cette classe aura cette variable. Vous pouvez faire 200 sous-classes et encore chacun d'entre eux ont cette variable.

note latérale: n'utilisez pas les majuscules comme nom de variable; la sagesse courante est que tous les identificateurs de majuscules se réfèrent à des constantes, c.-à-d. des morceaux de données non modifiables.

1
répondu dimitarvp 2010-03-03 12:19:49

pour ajouter des métadonnées par classe, peut-être qu'une annotation pourrait être la bonne façon de procéder.

Toutefois, vous ne pouvez pas imposer la présence d'une annotation dans l'interface, tout comme vous ne pouvez pas appliquer des membres statiques ou l'existence d'un constructeur.

1
répondu Joachim Sauer 2010-03-03 13:02:47

Non, Java ne supporte pas les variables abstraites. Il n'a pas vraiment beaucoup de sens.

quel changement spécifique à la" mise en œuvre " d'une variable pour que vous vous attendiez à ce qu'une sous-classe fasse?

Quand j'ai un abstractString variable dans la classe de base, que doit faire la sous-classe pour la rendre non abstraite?

-1
répondu Joachim Sauer 2010-03-03 12:13:38