2010-03-03 20 views
38

Vengo da C# dove questo è stato facile e possibile.Variabili astratte in Java?

ho questo codice:

public abstract class clsAbstractTable { 

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

} 

ma Eclipse mi dice che uso modificatore di illegale.

ho questa classe:

public class clsContactGroups extends clsAbstractTable { 


} 

voglio la variabile e metodo definito in modo tale, che Eclipse a richieda me, ho non attuate astratti variabili e metodi.

Come è necessario definire la mia classe astratta, quindi è necessario che venga richiesto di implementare gli abstract?

EDIT 1

creerò classi diverse per le diverse tabelle di db. Ogni classe dovrebbe avere la propria variabile TABLENAME, nessuna eccezione. Devo assicurarmi che questa variabile sia statica ogni volta che creo una nuova classe che estende la classe astratta.

Quindi nella classe astratta avrò un metodo es .: init();

Se in questo metodo init() chiamo TABLENAME, dovrebbe prendere il valore dalla sottoclasse.

qualcosa come questo dovrebbe funzionare anche fuori

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

EDIT 2

Voglio una costante (statica) definita in ogni classe ha il suo nome definito in astratto.

  • Definisco la variabile TABLENAME in astratto, ma nessun valore dato.
  • Creo un clsContactGroups, dovrei richiedere di implementare TABLENAME, questo è dove ottenere alcuni dati. es .: TABLENAME = "gruppi di contatti";
  • Creo un clsContacts di seconda classe, dovrei richiedere di implementare TABLENAME, questo è dove ottenere alcuni dati. es .: TABLENAME = "contatti";
    ecc ...
+0

Variabili astratte ??? –

+3

Non esistono variabili astratte in Java. Metodi astratti, sì. – duffymo

+0

la variabile TAG nel mio esempio. Voglio essere invitato a implementarli nelle altre classi. – Pentium10

risposta

45

Penso che la tua confusione sia con le proprietà C# rispetto a campi/variabili. In C# non è possibile definire campi astratti, anche in una classe astratta. Tuttavia, è possibile definire proprietà astratte poiché si tratta di metodi efficaci (ad esempio compilati in get_TAG() e set_TAG(...)).

Come alcuni hanno ricordato, non dovresti mai avere campi/variabili pubblici nelle tue classi, anche in C#. Diverse risposte hanno suggerito ciò che raccomanderei, ma non l'ho chiarito. Dovresti tradurre la tua idea in Java come una proprietà JavaBean, usando getTAG(). Allora le tue sottoclassi dovranno implementarlo (ho anche scritto un progetto con classi di tabelle che lo fanno).

Così si può avere una classe astratta definita come questo ...

public abstract class AbstractTable { 

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

    ... 
} 

Poi, in qualsiasi sottoclassi concrete si avrebbe bisogno di definire una variabile statica finale (costante) e restituire che dal getTag(), qualcosa in questo modo:

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:

campi

non è possibile sostituire ereditate (in C# o Java). Né puoi sovrascrivere i membri statici, che siano campi o metodi. Quindi anche questa è la soluzione migliore per questo. Ho modificato il mio esempio di metodo init in alto per mostrare come sarebbe stato usato, ancora una volta, pensiamo al metodo getXXX come a una proprietà.

+1

+1 Penso che questo risponda davvero alla domanda dell'OP, in quanto la premessa originale della domanda è sbagliata (che C# può avere campi astratti) – JonoW

1

Poiché non v'è alcuna implementazione di una variabile non può essere astratta;)

-1

No, Java non supporta le variabili astratte. Non ha molto senso, neanche.

Quale modifica specifica alla "implementazione" di una variabile si aspetta che una sottoclasse faccia?

Quando ho una variabile abstractString nella classe base, cosa dovrebbe fare la sottoclasse per renderla non astratta?

+0

Voglio assicurarmi che la sottoclasse definisca quella variabile. – Pentium10

+0

@ Pentium10: lo hai già detto, ma perché? A cosa servirebbe? Perché non definirlo nella classe base? –

+0

Voglio dare un valore nella sottoclasse. – Pentium10

6

Non esistono variabili astratte in Java (o C++).

Se la classe genitore ha una variabile e una classe figlio estende il genitore, il bambino non ha bisogno di implementare la variabile. Ha solo bisogno di accedere all'istanza del genitore. L'accesso get/set o protetto funzionerà.

"... quindi mi dovrebbe essere richiesto di implementare gli abstract"? Se estendi una classe astratta e non riesci ad implementare un metodo astratto, il compilatore ti dirà di implementarla o di contrassegnare la sottoclasse come astratta. Questo è tutto il suggerimento che otterrai.

+0

Voglio assicurarmi che la sottoclasse definisca quella variabile. Come posso essere sicuro? – Pentium10

+0

@ Pentium10: quale vantaggio avrebbe più semplicemente la definizione della variabile nella classe base in primo luogo? –

+0

Creerò diverse classi per diverse tabelle db. Ogni classe dovrebbe avere la propria variabile TABLENAME, nessuna eccezione. Devo assicurarmi che queste variabili siano statiche ogni volta che creo una nuova classe che estende la classe astratta. – Pentium10

49

Definire un costruttore nella classe astratta che imposta il campo in modo che le implementazioni concrete siano conformi alle specifiche richieste per chiamare/sovrascrivere il costruttore.

E.g.

public abstract class AbstractTable { 
    protected String name; 

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

Quando si estende AbstractTable, la classe non compilerà finché non si aggiunge un costruttore che chiama super("somename").

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

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

In questo modo gli implementatori devono impostare name. In questo modo puoi anche eseguire controlli (nulli) nel costruttore della classe astratta per renderlo più robusto. Ad esempio:

public AbstractTable(String name) { 
    if (name == null) throw new NullPointerException("Name may not be null"); 
    this.name = name; 
} 
+0

Mi picchio :) – seanhodges

+0

Ho bisogno che sia fatto con le variabili statiche. Poiché la variabile sarà statica per la classe implementata, come un tablename della classe. Non voglio passare ogni volta il tablename al costruttore. – Pentium10

+0

Le variabili statiche sono condivise tra tutte le istanze della classe. Se lo si imposta, verrà modificato/riflesso in ** tutte le istanze ** della classe, * indipendentemente * dell'implementazione. Lo vuoi * davvero *? Se è così, allora non vedo alcun beneficio nel renderli astratti ... Esattamente a causa del motivo precedente (che riguarda TUTTE le istanze). È anche tecnicamente impossibile perché viola l'ideologia OO. O hai bisogno di imparare ancora una volta Java/OO o di ripensare il tuo approccio/design. – BalusC

2

Basta aggiungere questo metodo per la classe di base

public abstract class clsAbstractTable { 

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

} 

Ora ogni classe che estende la classe base (e non vuole essere astratto) dovrebbe fornire un TAG

È potrebbe anche andare con la risposta di BalusC

+0

Questa non è una soluzione. La soluzione inizia con la ricerca di ciò che l'OP vuole ottenere. –

+0

Ho modificato le mie domande, spero sia chiaro cosa voglio raggiungere. – Pentium10

+1

Penso che questa sia la soluzione. Almeno l'unico che fornisce Java che soddisfa tutti i requisiti. Ogni sottoclasse dovrà fornire un'implementazione getTAG che possa restituire una stringa costante per tale sottoclasse. Secondo me, è ancora meglio che tenerlo in una variabile per istanza come nel codice originale. – PSpeed

2

Il meglio che si possa fare è disporre di accessor/mutatori per la variabile.
Qualcosa come getTAG()
In questo modo tutte le classi di implementazione dovrebbero implementarle.

Le classi astratte vengono utilizzate per definire il comportamento astratto e non i dati.

+0

Sì, voglio definire il comportamento astratto, intendo definire il nome, quindi tratterò i dati a livello di implementazione. – Pentium10

1

Perché si desidera che tutte le sottoclassi definiscano la variabile? Se ogni sottoclasse dovrebbe averlo, basta definirlo nella superclasse. A proposito, dato che è buona pratica OOP non esporre campi comunque, la tua domanda ha ancora meno senso.

1

Modificare il codice a:

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

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

In questo modo, tutte le classi che ereditano questa classe avrà questa variabile. Puoi fare 200 sottoclassi e ognuna di esse avrà questa variabile.

Nota a margine: non utilizzare CAPS come nome variabile; la saggezza comune è che tutti gli identificatori di maiuscole si riferiscono a costanti, cioè a parti di dati non modificabili.

+0

Quando creo una nuova classe, mi verrà chiesto di definire anche il TAG per quella classe? – Pentium10

+0

* Come alcuni hanno ricordato, non dovresti mai avere campi/variabili pubblici nelle tue classi * - Non c'è niente di sbagliato nei campi di 'public final' in' public final class', solo una questione di gusti. –

+0

Dopo aver letto la seconda modifica dell'OP, credo che stia cercando meccanismi OOP a livello di classe, che non sono supportati da Java. Puoi fare tutto l'OOP che vuoi con i metodi * instance *, ma non con i metodi * class * ('static' in Java). Dovrai (1) vivere con il fatto che ogni * istanza * avrà la propria copia della variabile, o (2) creare una HashMap globale per contenere le associazioni tra i nomi di classe e i valori di TAG su una classe per classe base. Entrambi sono imperfetti, ma hey, nessuno ha detto che Java capisce l'inglese. ;) – dimitarvp

1

Per aggiungere metadati per classe, forse un'annotazione potrebbe essere la strada giusta da percorrere.

Tuttavia, non è possibile imporre la presenza di un'annotazione nell'interfaccia, così come non è possibile applicare membri statici o l'esistenza di un costruttore specifico.

+0

Puoi mostrare un esempio? Sarei interessato a vedere come funziona. – byxor

0

Esistono due modi per definire proprietà astratte in java senza contrassegnare una proprietà come astratta.

1 ° modo: Definire un costruttore con parametri nella classe astratta, qualcosa di simile:

public abstract class clsAbstractTable { 
     private String TAG; 
     public clsAbstractTable (String TAG) { 
      this.TAG= TAG; 
     } 
} 

Quando si definisce un costruttore parametrizzata in una classe astratta, le sottoclassi sono costretti a definire i propri costruttori e chiamata il super costruttore, quindi passa il proprio TAG.

2 ° modo: Definire la proprietà come metodo getter, qualcosa di simile:

public abstract class clsAbstractTable { 
    public abstract String getTAG(); 
} 

In questo modo il valore di TAG proprietà è delegata a essere definito da ciascuna classe concreta.

Fonte: Define an abstract property in java