Datentypen Casting objects

HimBromBeere

Top Contributor
Tach auch,

gibts in Java gar keine Art von selbst-kreierten Casts oder wird das ausschließlich über .to<Klasse>-Funktionen gelöst?
Konkret: Ich habe eine Klasse Row (repräsentiert eine Datenzeile) und eine Klasse Feature (die von Row erbt). Eine Datenzeile hat ´nen Satz von Attributen.
Nun möchte ich in einer Klasse Table eine Methode zur Verfügung stellen, die mir alle Rows zurückgibt (also eine LinkedList<Row>). Erstelle ich nun jedoch eine Tabelle, die nicht aus einfachen Rows, sondern aus Features besteht, möchte ich natürlich auch features erhalten (also irgendwas der Form LinkedList<Features>). Ich fühl mich ja fast ein wenig schäbig das zu fragen, aber muss ich echt die Methode getAll() in der speziellen Tabelle neu implemntieren?

Steh grade auf´m Schlauch...
 
S

Spacerat

Gast
Also wenn Feature von Row erbt, dann lassen sich Features auch in eine LinkedList<Row> packen. Bei der Entnahme bzw. beim Lesen muss dann aber mit "instanceOf" verzweigt werden.
 

HimBromBeere

Top Contributor
Ööööööhm, nö...

ich möchte für eine normale Tabelle (Table) eine Methode getall() : LinkedList<Row>
und für eine spezielle Tabelle (SpatialTable) eine Methode getAll() : LinkedList<Feature> haben,
wobei zweitere nur die erste aufruft, damit ich den selben Quatsch nicht in zwei Klassen verwalten muss. Ich müsste also sowas kriegen wie
Code:
return (LinkedList<Feature>) super.getAll();

Also wenn Feature von Row erbt, dann lassen sich Features auch in eine LinkedList<Row> packen.
Das war mir soweit auch klar, die andere Richtung der Umwandlung interessiert mich ja :D
Bei der Entnahme bzw. beim Lesen muss dann aber mit "instanceOf" verzweigt werden.

Danke für die Info, spielt aber hier keine Rolle, da die zu lesenden Attribute für Feature über Row implementiert wurden (schlau wie ich war^^), sprich wenn ich von einem Feature sage:
Code:
feature.getGeometry()
, wird intern das folgende gemacht:
Code:
row.getValue('geometry');
 
Zuletzt bearbeitet:
B

bygones

Gast
die Methode muss als rueckgabe wert haben ala [c]Collection<? extends Row>[/c].
Komplett mit den 2 versch. Typen wirds nicht gehen. Ausser der Verwender weiss genau dass es sich um eine Feature Collection handelt, dann kann er die Collection direkt casten.
 

HimBromBeere

Top Contributor
die Methode muss als rueckgabe wert haben ala Collection<? extends Row>

Und wie sieht das aus, wenn ich nur ´ne Row haben möchte? Ist die Bedingung <? extends Row> für die Klasse Row denn auch erfüllt, sprich erweitert Row die Klasse Row?

EDIT: Schon erledigt, scheint tatsächlich mit<? extends Row> zu gehen... Danke
 
Zuletzt bearbeitet:

HimBromBeere

Top Contributor
Jtzt muss ich das Thema doch nochmal aufmachen.

Habe jetzt in meiner SpatialTable eine getAll()-Funktion wie folgt:
Java:
@Override
public Collection<? extends Row> getAll() {return super.getAll();}

und die überschreibt folgende Methode in der Klasse Table:
Java:
public Collection<? extends Row> getAll() {return (this.values.size() > 0 ? this.getRows(0, this.values.size() ): new LinkedList<Row>());}

Nun wird in einer Funktion in SpatialTable versucht, alle Features dieser Tabelle für eine Berechnung zu durchlaufen. Das sieht dasnn etwa so aus:
Java:
Iterator<Feature> i = this.getAll().iterator();

Hier meckert Eclipse wegen des Datentyps von getAll().Iterator(da dieser ja bekanntlich <? extends Row> heißt. Nun ist ja Feature aber eine Klasse, die <? extends Row> erfüllt, oder hab ich irgendwo einen Denkfehler?
 
B

bygones

Gast
generics und collections sind immer wieder heiter... Collection<Feature> ist keine Subclasse von Collection<? extends Row>, da in 2. eben ja noch andere Subklassen sein koennten.

[c]Iterator<? extends Row> i = this.getAll().iterator();[/c] anders gehts nicht
 

HimBromBeere

Top Contributor
Code:
Iterator<? extends Row> i = this.getAll().iterator();
anders gehts nicht

Hab ich probiert, nun ist jedoch das Problem, dass beim Durchlaufen der <? extends Row> über den Iterator ich ja keine Features erhalte, denn der Cast von i.next() auf Feature geht nicht. Daher ja meine ursprüngliche Frage des Castings von Objekten. Ich habe so langsam das Gefühl, ich hab meine Modellierung ein wenig unglücklich gewählt;(
 

Michael...

Top Contributor
Suchst Du eventuell etwas in dieser Art:
Java:
class Row {}
class Feature extends Row {}

class RowTable<T extends Row> {
	private List<T> list;
	...
	public List<T> getAll() {
		return list;
	}
}

class FeatureTable extends RowTable<Feature> {
	public void specialMethod() {
		Iterator<Feature> it = super.getAll().iterator();
	}
}
 

HimBromBeere

Top Contributor
JAU, das klingt anständig... werd´s mal ausprobieren.

EDIT: So, hab´s durchexerziert, es scheint erstmal zu funzen. Das ist erstmal schön. Nur zwei Sachen gefallen mir nich, aber damit muss ich scheinbar leben:
1. möchte ich eine Standard-Tabelle anlegen, muss ich trotzdem den Tepmlate-Typen <Row> angeben.
2. Möchte ich eine neue Zeile in eine Standard-Tabelle einfügen, muss ich die Row wieder in den Typ T casten.
Beides funktioniert, sieht aber irgendwie wie gesagt minimal unschön aus. Naja, muss ich mich dran gewöhnen, solange´s funktioniert...

Danke euch beiden...
 
Zuletzt bearbeitet:

Michael...

Top Contributor

HimBromBeere

Top Contributor
Doch wieder offen :D

zu 1.: Das hieße also, noch eine Standard-Implementierung für eine Table. Sinnvollerweise könnte ich dann die generische Klasse auch gleich noch abstrakt gestalten, dann kommt wenigstens keiner auf die dumme Idee, diese Klasse instanziieren zu wollen :D

zu 2.:
das sieht etwa so aus:
Java:
	/**
	 * Adds a single dataSet to the table.<br>
	 * @param values
	 * @throws IllegalArgumentException if the arguments do not match the tables metaData
	 * @throws ArgumentNumberException if the number of values does not match the number of dataTypes inside the tables metaData
	 */
	public void addRow(Object[] values) throws IllegalArgumentException, ArgumentNumberException {	
		
		if (values.length != this.metaData.size()) throw new ArgumentNumberException("Wrong number of arguments passed");
		
		
		String debugString = "Add new row to table {";
		
			// create an empty row
		Row row = new Row(this.metaData.toArray(new AttributeMetaData[0]));
		for (int i = 0; i < this.metaData.size(); i++) {
			// this may cause an IllegalArgumentException if the data does not match the rows metaData
			row.setValue(this.metaData.get(i).getName(), values[i]);
			debugString = debugString.concat("('" + this.metaData.get(i).getName() + "': " + values[i] + ")");
		}
		
		if (DEBUG) System.out.println(debugString+ "}");

		// if we get here everything went clear
		this.values.add((T) row);
		
	}
wobei AttributeMetaData eine Klasse zur Verwaltung je eines Names und des Datentyps in Form eines Class-Objektes darstellt. this.metaData ist eine Liste, die alle Attribute der Table beinhaltet und selbst vom Typ LinkedList<AttributeMetaData> ist...

Ich hoffe, du bist jetzt glücklich und wirst schlau daraus:toll:

Die Implementierung über Object[] erlaubt mir auch einen Aufruf, bei dem ich - vorrausgesetzt ich kenne die Ordnung und Datentypen der Attribute - diese Angaben nicht jedes Mal erst dazuschreiben muss, ähnlich einem
SQL:
Insert into <tabelle> values(...)
 
Zuletzt bearbeitet:

Michael...

Top Contributor
Sinnvollerweise könnte ich dann die generische Klasse auch gleich noch abstrakt gestalten,
Das ist sicherlich sinnvoll, in dieser Klasse könnte man dann auch eine
Code:
public abstract void addRow(Object[] values)
definieren. In der Implementierung der konkreten Klasse kann man dann ohne Cast mit dem entsprechenden Typ arbeiten.
 

HimBromBeere

Top Contributor
Das klingt nach einem Plan...

also nur nochmal zum Mitschreiben:

Java:
public class AbstractTable<T extends Row> {
    public abstract addRow(Object[]);
    public abstract addRow(T row);
}


public class DefaultTable extends AbstractTable<Row> {
    // hier kommen die beiden im vorigen Beitrag erwähnten addRow()-Methoden rein
}

public class SpatialTable extends DefaultTable<Feature> {
    // hier die Definition für ´s Hinzufügen eines Features
}

Super Idee... bekommt ´n Daumen ;)
 
Zuletzt bearbeitet:
S

Spacerat

Gast
Ab Java 1.5 funktioniert auch [c]addRow(Object ... objects);[/c]. Das ist der sog. Array-Parameter. Er sorgt dafür, das einzeln übergebene Objekte automatisch in ein Array gepackt werden, bevor sie an die Methode weitergegeben werden.
 

HimBromBeere

Top Contributor
Ab Java 1.5 funktioniert auch addRow(Object ... objects); . Das ist der sog. Array-Parameter
Meine Güte, das wird ja immer geiler mit euch... soooo macht das Ganze Spaß. So sieht´s noch hübscher aus. Das Array, was da raus kommt, kann ich dann wahrschlich über objects ansprechen, wenn ich recht annehme?


Daumen HOCH
 

HimBromBeere

Top Contributor
Wie komisch... jetzt hab ich die addRow() für das Array mal ausprobiert. Die fügt aber leider IMMER eine Row hinzu. Also hab ich die Methode addRow() in der Klasse SpatialTable überschrieben (damit auch wirklich die richtige Methoide verwendet wird):
Java:
@Override
	public void addRow(Object ... values) throws IllegalArgumentException, ArgumentNumberException {super.addRow(values);}

Kommen aber immer noch nur Rows heraus, keine Features, obwohl ich sogar meine Table nochmal zusätzlich in SpatialTable caste...
 
S

Spacerat

Gast
Im normalen Table sollte die Methode [c]addRow(Row ... rows)[/c] und im SpatialTable [c]addFeature(Feature ... features)[/c] heissen. Beide Methoden rufen ihrerseits dann [c]addRow(Object ... objects)[/c] des abstrakten Tables auf - also [c]super.addRow(rows)[/c] bzw. [c]super.addRow(features)[/c], welche dann allerdings auch dort implementiert sein muss, möglichst als protected final.
 

Michael...

Top Contributor
Das aktuelle Problem habe ich nicht verstanden. Vorschlag:
Java:
abstract class AbstractTable<T extends Row> {
	protected List<T> list = new ArrayList<T>();
	public void add(T value) {
		list.add(value);
	}
	public abstract void add(Object[] value);
}

class SpatialTable extends AbstractTable<Feature> {
	public void add(Object[] value) {
		//check value is valid and create Feature object
		list.add(new Feature());
	}
}
Dann ginge sowas:
Java:
	SpatialTable table = new SpatialTable();
	table.add(new Feature());
	table.add(new Object[] {});
	Iterator<Feature> it = table.list.iterator();
	while(it.hasNext()) {
		Feature feature = it.next();
		System.out.println(feature);
	}
 
B

bygones

Gast
ich skizziere mal eine moeglichkeit, ich kann nicht genau sagen, ob es dir hilft
Java:
public interface Element {
}

public interface Collector {
 Collection<? extends Element> getElements();
}

public interface SpecialElement extends Element {
}

public interface SpecialCollector extends Collector {
 // ueberschreibt getElements von Collector
 Collection<? extends SpecialElement> getElements();
}
d.h. man kann eine Methode mit einem mehr konkreten Typ in einer Subklasse ueberschreiben. Der Verwender von SpecialCollector bekommt dann eine Collection von SpecialElement, ein Verwender von Collector Element.

HIlft das fuer dein Feature/Row Problem?
 

HimBromBeere

Top Contributor
Danke für die zahlreichen Antworten, mir dünkt, das Problem scheint echt interessant zu sein :D


Ich sollte hinzuaddieren, dass ich meine Tabelle als AbstractTable definiere und anschließend erst als SpatialTable initialisiere. Das ist wie ich annehme der Grund dafür, dass der Compiler nicht den richtigen Datentypen für addRow() genereieren kann... also hab ich die Tabelle in ´ne SpatialTable gecastest, was komischerweise auch nicht wirklich viel geändert hat.

@Spacerat den Vorschlag find ich nich wirklich überzeugend, da ich dann in der Klasse SpatialTable sowohl eine addFeatzre als auch eine addRow habe, dass heißt, wenn mal irgendwann ein Irrer auf die Idee kommt, auf einer SpatialTable addRow(Objects) anzuwenden, wird trotzdem eine Row und kein Feature erstellt. Korrigier mich, wenn ich deinen Vorschlag falsch interpretiert hab...



EDIT: ich schicke mal die addRow in SpatialTable.
Java:
/**
 * Adds a new feature with a set of attributes into this table.
 */
@Override
public void addRow(Object ... values) throws IllegalArgumentException, ArgumentNumberException {
    LinkedList<Object> v = new LinkedList<Object>();
    v.add(this.currentID++);
    for (Object o: values) v.add(o);
			
    super.addRow(v.toArray(new Object[0]));
}
Eigentlich müsste ich noch überprüfen, ob in den übergeben Argumenten überhaupt eine geometrische information etahletn ist, aber dazu hab ich gerade keine rechte Muße...
Warum ich den Spaß in eine Liste umwandle, ums dann wieder als Array weiterzureichen: weil ich an erster Stelle eine automatisch inkrementierte ID hinzufügen möchte, denn diese soll ja verständlicherweise nicht vom Nutzer der Klasse angegegen werden (in einer normalen Tabelle gibt´s übrigens keine ID, nur in einer SpatialTable).

Nun ja... ich werd vlcht. auch einfach diese etwas generische Methode weglassen und nur noch addRow(Row) bzw. addRow(Feature) bereitstellen, dann muss man halt vor dem Aufruf der MEthode erst mal den Datensatz erstellen.
 
Zuletzt bearbeitet:

HimBromBeere

Top Contributor
Java:
AbstractTable<Feature> table = new SpatialTable();

Hat leider auch nix gebracht... es werden alle Attribute richtig übernommen (der Datensatz beinhaltet demnach auch die Attribute FID und geometry), aber der Datensatz ist und bleibt eine Row, kein Feature...

Ich lass den quatsch einfach erstmal, wenn ich mal viel Zeit und v.a. Muße hab, kpmmer ich mich mal um diese Implementierung...
 
S

Spacerat

Gast
@TS: Oh ja, da hast du was falsch verstanden, oder auch nur überlesen. Ich zeig's mal in ein Paar Codezeilen...
Java:
abstract class Table {
  private List<Object> rows = new ArrayList<Object>();

  protected void addRows(Object ... objects) {
    for(int i = 0; i < objects.length; i++) {
      rows.sdd(objects[i]);
    }
  }
}

final class RowTable extends Table {
  public void addRows(Row ... rows) {
    super.addRows(rows);
  }
}

final class FeatureTable extends Table {
  public void addFeatures(Feature ... rows) {
    super.addRows(rows);
  }
}
Natürlich gibt es trotz protected immer noch Möglichkeiten Table zu instanzieren und dessen [c]addRows()[/c] zu verwenden (Reflection, JNI u.ä), aber wie verrückt muss man sein?
 

HimBromBeere

Top Contributor
Bevor du jetzt denkst, dass dein Beitrag in der versekung verschwunden ist, schreib ich mal lieber was dazu :)


Jetzt hab ich kapiert, was du meintest. Das mit dem protected hab ich wahrscheinlich übersehen, daher das Missverständnis. Zumindest wäre das eine nahe liegende Variante, die sogar scheinbar ohne Generics auskommt. Aber bevor ich das Template wegnehme, muss ich noch was anderes erledigen... schreib dann, wenn ich wieder aufnahmefähig bin :D

Achja, eine addRows war überdies nie vorgesehen, nur eine addRow, also eine einzelne Zeile...
 

HimBromBeere

Top Contributor
So, hab´s nun glaub ich endlich... zum wievielten Mal sag ich das jetzt schon?

Naja, aufgrund der Tatsache, dass die addRow für die Spatialtable doch ein etwas anderes Vorgehen aufweist als man das standarsmäßig erwarten könnte, hab ich mich nun dafür entschieden, addRow in AbstractTable abstract zu gestalten (das war ja auch der Grund, weshalb die überhauot AbstractTable heißt). Die Klasse DefaultTable implementiert dann demenstprechend das Standard-Verhalten für addRow.

Danke trotzdem für die Mühe, ich hoffe nur, ich hab´s nun endlich gepackt :D

Jetzt brauch ich keine Angst mehr haben, dass jemand die addRow der AbstractTable ausführt, denn die gibts ja nur dem Namen nach :D
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
C Casting Java Basics - Anfänger-Themen 8
F Interface Casting Java Basics - Anfänger-Themen 13
N Generics und Casting eines Objekts Java Basics - Anfänger-Themen 1
temi (Down-)Casting Problem Java Basics - Anfänger-Themen 5
X Datentypen Casting?! Java Basics - Anfänger-Themen 7
P Casting Warning bei Iterator Java Basics - Anfänger-Themen 32
S Class Casting Allgemein Java Basics - Anfänger-Themen 3
Unsympath OOP Up- und Down-Casting Java Basics - Anfänger-Themen 3
R Casting Problem Java Basics - Anfänger-Themen 15
D Arry Casting Java Basics - Anfänger-Themen 30
B Anfängerprobleme (Casting,...) Java Basics - Anfänger-Themen 5
W Generische Klassen und Casting Java Basics - Anfänger-Themen 6
D OOP casting/get & set Methoden Java Basics - Anfänger-Themen 7
J Type-Casting Java Basics - Anfänger-Themen 8
G Überschreiben von Methoden beim Casting Java Basics - Anfänger-Themen 7
T Casting von Objekten Java Basics - Anfänger-Themen 2
G Casting, Ordinalzahl eines Buchstabens? Java Basics - Anfänger-Themen 4
P Casting von Object zu (String || Integer) Java Basics - Anfänger-Themen 8
B Casting variabel gestalten. Java Basics - Anfänger-Themen 9
U casting: ArrayList to String[] Java Basics - Anfänger-Themen 10
S Arraylist<Object> mit verschiedenen Objects ausgeben Java Basics - Anfänger-Themen 3
S Methoden Multi-Thread und Methoden Objects. Java Basics - Anfänger-Themen 1
G Moving Objects with Threads (implements Runnable) Java Basics - Anfänger-Themen 1
E Senden von Objects an Client. Variablenwerte kommen nicht an Java Basics - Anfänger-Themen 5
W Objects speichern Java Basics - Anfänger-Themen 4
W Auf Objects zugreifen Java Basics - Anfänger-Themen 17
S Array of objects und ständige Constructor-Aufrufe Java Basics - Anfänger-Themen 4
D Objects-Wie realiesieren. Java Basics - Anfänger-Themen 4
G fehler bei erzeugen eines objects Java Basics - Anfänger-Themen 4
P probleme mit variablen eines Objects Java Basics - Anfänger-Themen 13
T Typsicheres casten eines Objects Java Basics - Anfänger-Themen 5
L array of objects in liste packen Java Basics - Anfänger-Themen 2
R Textfile vs Serialized Objects Java Basics - Anfänger-Themen 4
R Objects, arrays usw. Java Basics - Anfänger-Themen 5
B equals() der Klasse Objects liefert unerwartetes Ergebnis Java Basics - Anfänger-Themen 17

Ähnliche Java Themen

Neue Themen


Oben