Variablen Möglich?: Cast einer Referenzvariable auf den Typ seines Objektes

Hallo,
ich hab mal folgende Frage (hab mich schon totgesucht):

Nehmen wir an ich habe eine abstrakte Oberklasse, die eine Methode hat. Diese Methode wird in den Unterklassen durch Einschubmethoden (Template Pattern) spezifiert.
Jedoch soll diese Methode (in der abstrakten Klasse) möglichst allgemein sein und damit verschiedene Objekte entgegennehmen können. Dazu sieht sie so aus:
Code:
public abstract class X{
........
  public void doSomething(Object o) {
   //hier sollte die Referenz "o" zu seinem wirklichen Typ werden. 
  //Also wenn hinter Object o ein Objekt vom Typ "Project" 
  //steht, soll der Referenztyp von o danach auch "Project" sein = Project o.
   //Abhandlung
  }
..........
}

Innerhalb der Methode sollte dann aber das "Object o" wieder seinen wirklichen Typ bekommen (also die Referenz "o" soll dann statt "Object" den Typ der Klasse haben, die hinter dieser Referenz steckt).
Google Suche und Experimente mit ".getclass().cast()" und ähnlichem haben nicht hingehauen.

Über den Sinn und Zweck bitte nicht diskutieren, der spezielle Typ wird später so in einer weiteren externen Methode benötigt.

Oder kann man hier mit Generics arbeiten (bin dort aber nich so fit drin)?
 
Zuletzt bearbeitet:
Code:
public <T extends AbstractClass> void doSomething(???? <T> o) {
So oder ähnlich muss es sicherlich sein.
Ich komme aber einfach nicht drauf, bzw. ich hab Generics noch nicht so 100%tig kapiert. Kann mir da jemand helfen? (Am besten ausnahmsweise bitte die Lösung, denn mir platzt nach dem langen Java-Tag heut gleich der Kopf). Besten Dank 🙂
 
Code:
public <T extends AbstractClass> void doSomething(???? <T> o) {
So oder ähnlich muss es sicherlich sein.
Ich komme aber einfach nicht drauf, bzw. ich hab Generics noch nicht so 100%tig kapiert. Kann mir da jemand helfen? (Am besten ausnahmsweise bitte die Lösung, denn mir platzt nach dem langen Java-Tag heut gleich der Kopf). Besten Dank 🙂

So aus dem Kopf müsste es wohl einfach

Code:
public <T extends AbstractClass> void doSomething(T o) {

sein.
 
Was gehen würde:

Java:
public abstract class AbstractClass<T> {
    public void doSomething(T t) {
        
    }
}
Java:
public class ConcreteClass extends AbstractClass<String> {
    @Override
    public void doSomething(String s) {
        
    }
}

Vielleicht suchst du aber auch einfach nur nach dem Visitor-Pattern?
 
Danke mvitz, das scheint so weit zu funktionieren 🙂
Edit: Danke euch beiden. hat mir weitergeholfen. Das Visitor-Pattern benötigte ich, denke ich, auf den ersten Blick nicht. Aber ich werd es mir auf jeden Fall nochmal genauer anschauen!
🙂
 
Zuletzt bearbeitet:
Wenn du mal erklären würdest was du damit später machen willst könnte man dir sicher einen geeigneten Tipp zur Umsetzung geben. Derzeit klingt das Ganze ein wenig krude was du da machst. Für 2 oder 3 verschiedene Typen (am Besten noch mit einem gemeinsamen Interface) würde ich auch deinen Ansatz verfolgen aber für "alle möglichen Typen" ist das etwas seltsam.
 
Sofern ohnehin eine abstrakte Klasse existiert, verstehe ich den Unterschied zwischen
Java:
public <T extends AbstractClass> void doSomething(T o)
und
Java:
public void doSomething(AbstractClass o)
nicht.

😕
 
Meines Erachtens gibt es keinen und ergibt in diesem Zusammenhang auch keinen Sinn, da Subklassen dann ebenfalls nur das machen können:
Java:
public class ConcreteClass extends AbstractClass {
	@Override
	public <T extends AbstractClass> void doSomething(T o) { // bzw. public void doSomething(AbstractClass o)
		
	}
}
Also im Prinzip nichts.

Bin daher auch etwas irritiert, dass es dem TE geholfen haben soll.
 
Tut mir Leid Leute..Ich hatte den Tag noch gemerkt, dass meine gewünschten Zielklassen (in die Object o gecastetd werden soll), gar keine Unterklasse von der abstrakten Klasse sind (war nicht mein Code; wollte diesen etwas vereinfachen durch die Idee mit den Generics).
Also wie ihr schon gesagt habt, besteht zwischen den zwei Lösugnen kein Unterschied, aber ich kann sie jetzt doch nicht so anwenden.

Aber mal davon ab: Geht es trotzdem mit irgendwelchen Tricks, dass wenn ich ein Object o in einer Methode erwarte, ich diese Referenz auf den wahren (Klassen-)Typ von o bringen kann? Ohne die Klasse (wo sich die Methode befindet) irgendwie mit dem Klassen-Typ von "o" verwandt ist?

Mit geht es darum, dass ich sonst in den Einschubmethoden die Referenz "o" auf die enstprechende Klasse casten müssten, um an dessen Methoden ranzukommen.
 
Nope, Interface geht auch nicht hehe. Die übergebenen Objekte haben alle unterschiedliche Methoden / Zwecke.
Ich caste jetzt in den Einschubmethoden auf die jeweilige Klasse. Das ist am einfachsten. Anders hätte ich natürlich vor dem Aufruf der Einschubmethode schon automatisch casten alssen können und mir das dann in den Einschubmethoden erspart. Aber das macht jetzt nichts.
Danke für die Hilfe Leute 🙂.
 
angenommen, das was du wünschst ginge mit einem imaginären Konstrukt X,
was würde das für dich bedeuten, was hättest du davon, welchen Code würdest du damit schreiben?


Code:
public abstract class X{
........
  public void doSomething(Object o) {
   //hier sollte die Referenz "o" zu seinem wirklichen Typ werden. 
  //Also wenn hinter Object o ein Objekt vom Typ "Project" 
  //steht, soll der Referenztyp von o danach auch "Project" sein = Project o.
   //Abhandlung
  }
..........
}
wenn du ganz konkret 'Project'-Code schreiben willst, dann caste einfach auf Project, das geht,
wenn du mehrere fragliche Klassen kennst dann brauchst du auch mehreren Code, der kaum in derselben Zeile steht,
du brauchst eine Unterscheidung per if und else in verschiedene Abläufe, mit instanceof-Test und Cast wärst du wiederum gut bedient,

am ehesten noch könntest du hoffen, dass etwa bei vorhandenen Untermethoden für Typ A, B, C
ein Code
Java:
call(o);
automatisch die richtige Untermethode wählt, statt mühsamen Standardcode
Java:
if (typA) {
call( (A) o);
} else if (typB) ...
auszuprogrammieren, also nur ein Weiterreichungsproblem, kein direkter Code,
diesen Fall gibt es nicht, also keine Java-Unterstützung dazu,

für alles andere macht es schlicht keinen Sinn überhaupt etwas in der Art zu wünschen,
es ließe sich für nichts anwenden, oder noch mal gefragt: wie genau stellst du dir einen Nutzen vor?
 
Zuletzt bearbeitet von einem Moderator:
Der Nutzen sollte ganz trivial sein, nämlich dass ich mir den Cast in jeer Einschubmethode spare 😉
Ich dachte halt, dass es vllt. eine einfache Java-Implemt. dafür schon gäbe oder etwas in der Art. Da es ja nicht der Fall zu sein scheint, caste ich halt in den Einschubmethoden der jeweiligen Unterklasse.
 
> nämlich dass ich mir den Cast in jeer Einschubmethode spare

du meinst vielleicht genau das was ich schon geschrieben habe,
ansonsten kann ich darin keine Bedeutung erkennen, nur Code, eben Pseudocode, wäre hilfreich

aber muss auch absolut nicht sein, wenn Thema für dich schon beendet
 
Ich denke shcon, dass wir das gleiche verstehen. Aber hier gerne nochmal Code (hab grad keine Zeit für Pseudocode)

Code:
public abstract class AbstractClass {

    public void saveObject(Object o) {
        .....[COLOR="Red"]//Ich dachte hier hätte man einen autom. Cast von der Referenz "o" auf seinen Klassentyp machen können, der dann natürlich an die Einschubmethode "saveSpecific()" weitergeleitet wird.[/COLOR]
        
        saveSpecific(o);  //Da das anscheinend nicht geht, übergebe ich jetzt hier Object o und caste es dort in der Einschubmethode (s.u.).
        ......
    }

}
//Eine von AbstractClass erbenden Klassen
public class Project extends AbstractClass{
    @Override
    void saveSpecific(Object o) {
        Sprint p = (A) o;
         .....//speichere Sachen aus p
}
 
Zuletzt bearbeitet:
mit Generics geht übrigens folgende Richtung:
Java:
    abstract class AbstractClass<T>
    {

        abstract void saveSpecific(T t);

        void saveObject(Object o)
        {
            saveSpecific((T)o);
        }
    }

    class Project
        extends AbstractClass<Sprint>
    {

        void saveSpecific(Sprint o)
        {

        }

    }

    class Sprint
    {
    }
aber auch viel zu tippen pro Klasse, nur um einmal Cast (Sprint) zu sparen ist <Sprint> wohl kaum besser 😉
 

Zurück
Oben