2012-05-09 10 views
6

Ciò di cui ho veramente bisogno è poter dichiarare variabili regolari in un'interfaccia e implementare quell'interfaccia in due classi che non avrei dovuto dover ripetere nuovamente in ciascuna di esse classe (cioè class.data.variables invece di class.variables). C'è un modo per raggiungere lo stesso obiettivo in modo diverso?Come posso avere due classi condividere la stessa definizione di variabile

Per fornire maggiori dettagli. In sostanza, ho creato un piccolo programma di disegno che elimina JLabels su un JPanel che si trova su un JScrollPane. Poiché ho un design specifico per questi JLabels (cioè non sono solo per il disegno, rappresentano oggetti aerei per questa applicazione), ho una classe che estende JLabel e aggiunge le mie variabili specifiche dell'applicazione. In definitiva, leggo e scrivo un file XML con queste variabili in modo che possano caricare e salvare i loro disegni. Dal momento che non posso usare questa classe estesa per le mie definizioni XML perché urla sulla classe genitore anche se ho detto di avere NONE come accessor (ho letto che c'è un bug), devo creare una classe identica e copiare i valori indietro e avanti per il salvataggio e il caricamento. Non un grosso problema tranne quando aggiungo una variabile alla classe estesa di JLabel e dimentico di aggiungerla alla classe mimica XML e alle successive routine di copia.

Quindi, sarebbe bello se potessi creare una classe (ad esempio CellDataRecord.java) che contenesse le dichiarazioni di dati extra e che la classe sia utilizzata in entrambi i posti (l'estensione JLabel e i dati XML) senza dover avere qualcosa come XML.data.CellDataRecordXXX.

+0

cosa si sta descrivendo sarebbe stato chiamato a * mix-in * - e Java non ha quelli. Dovrai ricorrere a un modello o all'altro, con cui hai già familiarità. –

+0

stesso problema del mio. – Acewin

risposta

5

È possibile farlo con l'ereditarietà o utilizzando un'interfaccia, in cui la variabile è impostata come costante nella classe genitore. Dal momento che si sta estendendo un JLabel, è necessario implementare l'interfaccia su entrambe le classi:

public interface MyInterface { 
    int someint = 9; 
} 

public class MyClass1 extends JLabel implements MyInterface { 
    //this class has access to `someint` 
} 

public class MyClass2 extends JLabel implements MyInterface { 
    // also has access to `someint` 
} 

Modifica

Dal momento che si vuole essere in grado di cambiare la stessa variabile da classi diverse, è necessario assicurarsi che si aren' t cambiando le copie e stiamo cambiando la stessa variabile, quindi dovresti usare una parola chiave volatile sulla variabile per indicare a java che tutti i thread dovrebbero controllare il valore prima di aggiornarlo.

Ora è necessario disporre di una classe separata in modo che le istanze possano essere create da altre classi per ottenere il valore. Devi usare la parola chiave static per assicurarti che una copia sia conservata per tutte le istanze di classe.

public class MyVariableWrapper { 
    public static volatile int some_var = 9; 
    public void updateSomeVar(int newvar) { 
     some_var = newvar; 
    } 
    public int getSomeVar() { return some_var; } 
} 

Ora le altre due classi solo fare questo:

public class MyClass1 extends JLabel { 
    MyVariableWrapper myVariableWrapper; 
    MyClass1() { 
     super(); 
     myVariableWrapper = new MyVariableWrapper(); 
     // now I have access to `some_var` 
    } 
} 

public class MyClass2 extends JLabel { 
    MyVariableWrapper myVariableWrapper; 
    MyClass2() { 
     super(); 
     myVariableWrapper = new MyVariableWrapper(); 
     // now I have access to the same `some_var` as MyClass1 
    } 

    // this is a wrapper method for your convenience 
    // since you don't like the excess code when accessing the variable 
    public int getSomeVar() { 
     return myVariableWrapper.some_var; 
     // or myVariableWrapper.getSomeVar(); 
    } 
    public void setSomeVar(int newvar) { 
     myVariableWrapper.some_var = newvar; 
     // or myVariableWrapper.setSomeVar(newvar); 
    } 
} 

Ora si può fare questo:

MyClass2 myClass2 = new MyClass2(); 
System.out.println(""+myClass2.getSomeVar()); 
+0

La mia comprensione è che se uso un'interfaccia tutte le mie "variabili" diventano "costanti" e ho bisogno che siano variabili. Quindi, se ho capito bene, un'interfaccia non funzionerà per me. –

+0

@JesterHawk Oh, giusto, devi solo dichiarare la variabile nella sua classe come 'static' e' volatile', e quindi creare istanze di quella classe dalle due classi che hanno bisogno della variabile. Ecco un esempio di utilizzo di una variabile volatile in java: http://ilkinbalkanay.blogspot.co.uk/2007/10/volatile-variables-in-java.html – Ozzy

+0

@JesterHawk vedere la mia risposta aggiornata anche – Ozzy

1

Non sono sicuro di capire al 100% il problema, ma dalle prime righe della descrizione, invece di implementare un'interfaccia, è possibile definire una classe astratta e far sì che le classi la estendano. In questo modo, sarai in grado di definire gli attributi nella classe astratta e questi saranno comuni a tutte le sottoclassi.

+1

Sta già estendendo 'JLabel', quindi non andare. –

+0

Sì, il problema è che si estende JLabel perché ho bisogno che venga disegnata su un JPanel. E poiché non posso avere una classe che estenda sia JLabel che una classe Abstract (che sarebbe davvero interessante e utile), ciò non funziona. –

+0

Ho provato ad avere JLabel come componente della classe, ma ho riscontrato problemi con la parte del disegno.Probabilmente la mia mancanza di conoscenza. Ma essenzialmente ho avuto problemi con la rimozione. Ad esempio, l'utente ricomincia e fa clic per eliminare una "cella" che contiene la JLabel. Potrei farlo rimuovere dal riquadro ma trovando quale "cella" fosse nella lista degli array si è dimostrata instabile. Stavo controllando il componente ma non lo trova sempre. Quindi, mi è stato lasciato senza un modo affidabile per rimuovere la "cella" sia da JPanel che da ArrayList. Di nuovo, probabilmente la mia mancanza di conoscenza. –

Problemi correlati