Ich spiele grade beim Refactoring mit Generics rum, und habe meine Konzepte nochmal überdacht,
ich haben eine Klasse angelegt die meine Daten in Form eines VO's halten soll, diese Klasse ist generisch :
Ich möchte eigentlich den Typ des ValueObjectes erst in der jeweiligen Spezialisierung festlegen , oder sollte ich dazu übergehen dann wirklich in jeder Speziealisierung ein eigenes VO zu halten ? Was eigentlich nicht mein Ziel war .
Ein Object dieser Klasse möchte ich nun in einer abstrakten klasse als Attribut verwenden :
Hiervon möchte ich nun Subklassen erstellen :
wie z.B Client oder auch User ,
die Frage ist nun , wie kann ich , bis auf das Verwenden einer Wildcard nun z.B im Konstruktor der noch nicht aufgeführten Klasse User/Client festlegen das hier nur Strings im Konstruktor übergeben werden dürfen ?
Muss ich tatsächlich alle Argumente Casten ? oder gibt es da einen schöneren Weg als das hier :
ich dachte da ich in Entity eh mit <? extends Object> arbeite müsste ich nicht zwingend Casten, aber pustekuchen... also muss ich wohl tatsächlich Client/Entity als Generisch deklarieren oder ?
EDIT
Ich müsste ja bereits hier den Konstruktor anders deklarieren sonst lege ich mich ja schon auf Object fest....
aber wie wenn Entity nicht generisch ist ^^ ?
Sprich kann ich ja nicht einfach T...t verwenden , da der Platzhalten in Entity nicht bekannt ist.
Wenn ich Entity einfach als Generisch deklariere funktioniert das reibungslos, da ich einfach den Platzhalter übergebe :
und dann in Client
Ist das so gewollt oder gibt es da noch einen anderen Weg ?
Sinn dahinter ist das ich nachher nicht bei den ganzen Settern jedes Feld wie z.B
in der Klasse Client
auf den Rückgabetyp Casten muss....
ich haben eine Klasse angelegt die meine Daten in Form eines VO's halten soll, diese Klasse ist generisch :
Java:
import java.io.Serializable;
import java.util.ArrayList;
@SuppressWarnings("serial")
public class ValueObject<T> implements Serializable{
private ArrayList<T> data;
public ValueObject(){
init();
}
public ValueObject(ArrayList<T> list){
data = list;
}
@SafeVarargs
public ValueObject(T...t){
this();
if(t.length > 0) {
for (int i = 0; i < t.length; i++) {
data.add(t[i]);
}
}
}
private void init(){
data = new ArrayList<>();
}
public ValueObject<T> copy(){
return new ValueObject<>(getData());
}
@Override
public boolean equals(Object o){
boolean val = false;
ValueObject<?> other = (ValueObject<?>) o;
for (int i = 0; i < data.size(); i++) {
if(data.size() == 0) {
val = this == other;
}
val = data.get(i) == other.get(i);
}
return val;
}
public ArrayList<T> getData() {return data;}
public int getSize() {return data.size();}
public T get(int index) {return data.get(index);}
}
Ich möchte eigentlich den Typ des ValueObjectes erst in der jeweiligen Spezialisierung festlegen , oder sollte ich dazu übergehen dann wirklich in jeder Speziealisierung ein eigenes VO zu halten ? Was eigentlich nicht mein Ziel war .
Ein Object dieser Klasse möchte ich nun in einer abstrakten klasse als Attribut verwenden :
Java:
import java.io.Serializable;
import editor.valueObjects.ValueObject;
@SuppressWarnings("serial")
public abstract class Entity implements Serializable{
public static int ID = 1;
protected ValueObject<? extends Object> valueObject;
public Entity(Object...objects){
valueObject = new ValueObject<>(objects);
}
public Entity(ValueObject<? extends Object> obj){
valueObject = obj;
}
public abstract int getID();
public abstract Entity copy();
public abstract String getSaveName();
public ValueObject<? extends Object> getValueObject() {return valueObject;}
}
Hiervon möchte ich nun Subklassen erstellen :
wie z.B Client oder auch User ,
die Frage ist nun , wie kann ich , bis auf das Verwenden einer Wildcard nun z.B im Konstruktor der noch nicht aufgeführten Klasse User/Client festlegen das hier nur Strings im Konstruktor übergeben werden dürfen ?
Muss ich tatsächlich alle Argumente Casten ? oder gibt es da einen schöneren Weg als das hier :
Java:
@SuppressWarnings("serial")
public class Client extends Entity{
public Client(String...input){
super(input); // <--- hier sagt er mir ich müsste die Varags auf Object Casten
/*
* gibt es keine Möglichkeit dies anders zu realisieren außer die Klasse
* Entity/Client selbst Generisch zu machen ?
* Oder muss ich Casten ?
*/
}
@Override
public int getID(){
return 0;
}
@Override
public Entity copy(){
return null;
}
@Override
public String getSaveName(){
return null;
}
}
ich dachte da ich in Entity eh mit <? extends Object> arbeite müsste ich nicht zwingend Casten, aber pustekuchen... also muss ich wohl tatsächlich Client/Entity als Generisch deklarieren oder ?
EDIT
Ich müsste ja bereits hier den Konstruktor anders deklarieren sonst lege ich mich ja schon auf Object fest....
Java:
public Entity(Object...objects){
valueObject = new ValueObject<>(objects);
}
aber wie wenn Entity nicht generisch ist ^^ ?
Sprich kann ich ja nicht einfach T...t verwenden , da der Platzhalten in Entity nicht bekannt ist.
Wenn ich Entity einfach als Generisch deklariere funktioniert das reibungslos, da ich einfach den Platzhalter übergebe :
Java:
import java.io.Serializable;
import editor.valueObjects.ValueObject;
@SuppressWarnings("serial")
public abstract class Entity<T> implements Serializable{
protected static int ID = 1;
protected ValueObject<T> valueObject;
@SafeVarargs
public Entity(T...t){
valueObject = new ValueObject<>(t);
}
public Entity(ValueObject<T> obj){
valueObject = obj;
}
public abstract int getID();
public abstract Entity<T> copy();
public abstract String getSaveName();
public ValueObject<? extends Object> getValueObject() {return valueObject;}
}
und dann in Client
Java:
@SuppressWarnings("serial")
public class Client extends Entity<String>{
public Client(String...input){
super(input);
}
@Override
public int getID(){
return 0;
}
@Override
public Entity<String> copy(){
return null;
}
@Override
public String getSaveName(){
return null;
}
}
Ist das so gewollt oder gibt es da noch einen anderen Weg ?
Sinn dahinter ist das ich nachher nicht bei den ganzen Settern jedes Feld wie z.B
in der Klasse Client
Java:
public String getName() {return valueObject.get(0);}
auf den Rückgabetyp Casten muss....
Zuletzt bearbeitet: