| Autor |
Nachricht |
freakC++
Mitglied
Benutzerprofil
Anmeldungsdatum: 26.04.2008
Beiträge: 1747
|
freakC++ Mitglied
11:32:37 11.01.2012 Titel: |
Problem mit instanceof |
Zitieren |
Hallo zusammen,
ich habe eine Methode, die überprüfen soll, ob sich zwei Objekte gleichen. Dazu möchte ich zuerst einmal überprüfen, ob das übergebene Objekt überhaupt von derselben Klasse bzw. von einer Unterklasse abstammt. Dazu möchte ich das aktuelle Objekt (this) und instanceof verwenden.
Jetzt habe ich ganz banale Syntaxprobleme, die mir Onkel Google auch nicht lösen kann.
| Code: | public boolean equals (Object o) {
if(o instanceof this)
return true;
}
| |
| Code: | public boolean equals (Object o) {
if(o instanceof this)
return true;
}
| |
| Code: | public boolean equals (Object o) {
if(o instanceof this)
return true;
}
| |
Das ist so falsch. Doch vielleicht versteht ihr, was ich haben möchte . Könnt ihr mir sagen, wie die Syntax richtig lauten muss?
Vielen Dank
lg, freakC++ |
_________________ Gdzie jest mój pstrąg?
Zuletzt bearbeitet von freakC++ am 11:39:17 11.01.2012, insgesamt 1-mal bearbeitet |
|
 |
freakC++
Mitglied
Benutzerprofil
Anmeldungsdatum: 26.04.2008
Beiträge: 1747
|
freakC++ Mitglied
11:40:23 11.01.2012 Titel: |
|
Zitieren |
Wahrscheinlich habe ich es wieder selbst herausgefunden....
Wie der Name "instanceof" ja schon andeutet, darf recht davon kein Objekt, sondern die Klasse stehen. this ist jedoch ein Objekt.
Naja, danke trotzdem!
lg, freakC++ |
_________________ Gdzie jest mój pstrąg?
|
|
 |
icarus2
Mitglied
Benutzerprofil
Anmeldungsdatum: 20.09.2009
Beiträge: 1163
|
icarus2 Mitglied
11:40:59 11.01.2012 Titel: |
|
Zitieren |
Die Syntax des Konstrukts ist
| Java Code: | | objektName instanceof KlassenName
| |
| Java Code: | | objektName instanceof KlassenName
| |
| Java Code: | | objektName instanceof KlassenName
| |
Aber this instanceof Object ist nicht wirklich sinnvoll, da onehin jedes Objekt eine Instanz von Objekt ist, dieser Ausdruck also konstant true ergibt.
Was fuer Objekte moechtest du denn vergleichen? |
|
|
|
 |
freakC++
Mitglied
Benutzerprofil
Anmeldungsdatum: 26.04.2008
Beiträge: 1747
|
freakC++ Mitglied
11:50:00 11.01.2012 Titel: |
|
Zitieren |
Hey icarus2!
Danke trotzdem für die Antwort. Mir kommt es ganz gelegen, dass Du antwortest, denn ich habe gemerkt, dass sich mein Problem doch noch nicht ganz aufgelöst hat.
Ich habe eine Klasse A mit zwei protected Attributen (color, size). Eine Klasse B erbt nun von dieser Klasse A.
Klasse B hat nun die Methode "equals" die überprüfen soll, ob ein willkürlich übergebenes Objekt dem aktuellen gleicht.
Gleichen heißt: Das übergebene Objekt ist von derselben Klasse und der Inhalt der vererbten protected Variablen ist gleich. Da weiß ich aber nicht so ganz, wie ich diesen Vergleich anstellen soll:
| Code: | 1 2 3 4 5 6 7 8 9 | 1 2 3 4 5 6 7 8 9 | public boolean equals (Object o) {
boolean res = o instanceof B;
boolean sameDescription = this.color.equals(o) && this.size == o.size;
//Das funktioniert so nicht, da ich ja gar nicht weiß, ob "o" zu meiner Klasse gehört und damit auch nicht sagen kann, ob es die Attribute size und color hat.
return res && sameDescription;
}
| |
| Code: | 1 2 3 4 5 6 7 8 9 | public boolean equals (Object o) {
boolean res = o instanceof B;
boolean sameDescription = this.color.equals(o) && this.size == o.size;
//Das funktioniert so nicht, da ich ja gar nicht weiß, ob "o" zu meiner Klasse gehört und damit auch nicht sagen kann, ob es die Attribute size und color hat.
return res && sameDescription;
}
| |
| Code: | 1 2 3 4 5 6 7 8 9 | public boolean equals (Object o) {
boolean res = o instanceof B;
boolean sameDescription = this.color.equals(o) && this.size == o.size;
//Das funktioniert so nicht, da ich ja gar nicht weiß, ob "o" zu meiner Klasse gehört und damit auch nicht sagen kann, ob es die Attribute size und color hat.
return res && sameDescription;
}
| |
Wie muss der Zugriff auf "size" und "color" von o lauten? |
_________________ Gdzie jest mój pstrąg?
Zuletzt bearbeitet von freakC++ am 11:52:48 11.01.2012, insgesamt 2-mal bearbeitet |
|
 |
icarus2
Mitglied
Benutzerprofil
Anmeldungsdatum: 20.09.2009
Beiträge: 1163
|
icarus2 Mitglied
12:00:50 11.01.2012 Titel: |
|
Zitieren |
Ich bin mir noch nicht ganz sicher was du machen willst. Ich fange mal vorne an.
1.
Der Ausdruck
| Java Code: | | boolean res = o instanceof B;
| |
| Java Code: | | boolean res = o instanceof B;
| |
| Java Code: | | boolean res = o instanceof B;
| |
ist immer falsch, da die Klasse Object nicht von B erbt. Wenn du ein Objekt der Klasse A oder B nach Object castet (oder das implizit passiert), so weiss das Laufzeitsystem nicht mehr, dass es sich dabei um ein Objekt von A oder B handelt. Es ist einfach ein Object.
2.
Du versuchst auf den Attributen color und size (welche Typen haben die denn?) die Methode equals(...) aufzurufen. Haben die Typen von color und size denn eine Methode equals(...) definiert?
Vielleicht hilft dir das etwas. Da ich noch nicht genau weiss was du machen moechtest ist es etwas schwierig dir einen konkreten Hinweis zu geben. |
Zuletzt bearbeitet von icarus2 am 12:04:15 11.01.2012, insgesamt 1-mal bearbeitet |
|
 |
freakC++
Mitglied
Benutzerprofil
Anmeldungsdatum: 26.04.2008
Beiträge: 1747
|
freakC++ Mitglied
12:09:23 11.01.2012 Titel: |
|
Zitieren |
Mmmhh...ok, ich versuche mich noch einmal etwas konkreter auszudrücken.
Ich habe die folgende Klasse A:
| Code: | 1 2 3 4 5 6 7 8 9 10 11 | 1 2 3 4 5 6 7 8 9 10 11 | public abstract class A {
protected String title;
protected int price;
public A (String t, int p) {
title = t;
price = p;
public abstract boolean equals(Object o);
}
}
| |
| Code: | 1 2 3 4 5 6 7 8 9 10 11 | public abstract class A {
protected String title;
protected int price;
public A (String t, int p) {
title = t;
price = p;
public abstract boolean equals(Object o);
}
}
| |
| Code: | 1 2 3 4 5 6 7 8 9 10 11 | public abstract class A {
protected String title;
protected int price;
public A (String t, int p) {
title = t;
price = p;
public abstract boolean equals(Object o);
}
}
| |
Nun habe ich Klasse B, die von A beerbt wird:
| Code: | 1 2 3 4 5 6 7 8 9 10 | 1 2 3 4 5 6 7 8 9 10 | public class B extends A {
public B (String t, int p) {
super(t,p);
public boolean equals (Object O) {
//...
}
}
}
| |
| Code: | 1 2 3 4 5 6 7 8 9 10 | public class B extends A {
public B (String t, int p) {
super(t,p);
public boolean equals (Object O) {
//...
}
}
}
| |
| Code: | 1 2 3 4 5 6 7 8 9 10 | public class B extends A {
public B (String t, int p) {
super(t,p);
public boolean equals (Object O) {
//...
}
}
}
| |
Ich möchte ich, dass die Methode "equals" jetzt überprüft:
1.) Ist o vom Typ B?
2.) Wenn o vom Typ B ist, stimmt dann der Inhalt von "title" und "price" mit dem des aktuellen Objekts von B überein.
Wenn der Ausdruck "boolean res = o instanceof B" immer falsch ist, dann frage ich mich, wie ich überprüfen soll, ob o vom Typ B ist (Ich muss "instanceof" verwenden).
Und falls dann "o" vom Typ B ist, wie kann ich dann auf die Attribute "title" und "price" zugreifen?
Ich hoffe, mein Anliegen ist etwas klarer geworden
Vielen Dank
lg, freakC++
EDIT: Ich habe mit vertan. o muss vom Typ "A" sein und nicht vom Typ "B". Also muss es "o instanceof A" oder so ähnlich heißen. |
_________________ Gdzie jest mój pstrąg?
Zuletzt bearbeitet von freakC++ am 12:12:58 11.01.2012, insgesamt 1-mal bearbeitet |
|
 |
icarus2
Mitglied
Benutzerprofil
Anmeldungsdatum: 20.09.2009
Beiträge: 1163
|
icarus2 Mitglied
12:20:16 11.01.2012 Titel: |
|
Zitieren |
Ich glaube ich habe die Loesung gefunden. Erstmals sorry, denn ich hatte falsch im Kopf, dass o instanceof A immer false liefert. Das stimmt so natuerlich nicht - mein Fehler.
So muesste es klappen:
| Java Code: | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public class B extends A {
public B (String t, int p) {
super(t,p);
}
public boolean equals (Object o) {
A temp = null;
if ( o instanceof A ) // (1)
temp = (A) o;
else
return false;
return this.title.equals(temp.title) && this.price == temp.price;
}
}
| |
| Java Code: | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public class B extends A {
public B (String t, int p) {
super(t,p);
}
public boolean equals (Object o) {
A temp = null;
if ( o instanceof A ) // (1)
temp = (A) o;
else
return false;
return this.title.equals(temp.title) && this.price == temp.price;
}
}
| |
| Java Code: | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public class B extends A {
public B (String t, int p) {
super(t,p);
}
public boolean equals (Object o) {
A temp = null;
if ( o instanceof A ) // (1)
temp = (A) o;
else
return false;
return this.title.equals(temp.title) && this.price == temp.price;
}
}
| |
(1)
Wenn o eine Instanz von A ist, dann castest du o vom Typ Object nach A. Sonst gibst du false zurueck.
Mit dem Objekt temp der Klasse A (also o nach A gecastet) kannst du dann frei auf die Attribute zugreifen.
Ist es das was du haben moechtest?
*Edit
Nur noch kurz, dass es keine Verwirrung gibt:
Das equals bei
| Java Code: | | this.title.equals(temp.title)
| |
| Java Code: | | this.title.equals(temp.title)
| |
| Java Code: | | this.title.equals(temp.title)
| |
hat nichts mit dem equals der Klasse B zu tun. Es ist das equals, das in der Klasse String definiert ist. |
Zuletzt bearbeitet von icarus2 am 12:21:47 11.01.2012, insgesamt 1-mal bearbeitet |
|
 |
freakC++
Mitglied
Benutzerprofil
Anmeldungsdatum: 26.04.2008
Beiträge: 1747
|
freakC++ Mitglied
12:31:15 11.01.2012 Titel: |
|
Zitieren |
Hallo icarus2,
jaa, das ist genau das, was ich brauche. Super! Jetzt funktioniert es. Herzlichen Dank!
Noch zwei Anmerkungen:
1.)
Ist dieser expliziere Cast hier notwendig oder einfach nur schön? "temp" ist immerhin schon vom Typ A?
2.)
| icarus schrieb: |
Das equals bei
| Java Code: | | this.title.equals(temp.title)
| |
| Java Code: | | this.title.equals(temp.title)
| |
| Java Code: | | this.title.equals(temp.title)
| |
hat nichts mit dem equals der Klasse B zu tun. Es ist das equals, das in der Klasse String definiert ist. |
[/quote]
Gut, dass Du es ansprichst. Es war mir zwar klar, aber doppelt hält besser. Der Unterschied zwischen "equals" und "==" ist wohl der vergleichbar mit "gleich" und "identisch"
Danke dir noch einmal!
lg, freakC++ |
_________________ Gdzie jest mój pstrąg?
|
|
 |
freakC++
Mitglied
Benutzerprofil
Anmeldungsdatum: 26.04.2008
Beiträge: 1747
|
freakC++ Mitglied
12:41:00 11.01.2012 Titel: |
|
Zitieren |
bzw. warum muss dieser Cast sein? Ich sehe ja bei mir, dass es sonst einen Fehler gibt
edit: Irgendwie ist es mir klar, weil o ja vom Typ "object" ist. Aber durch die if-Abfrage weiß ich doch, dass es eine Instanz von Product ist.... |
_________________ Gdzie jest mój pstrąg?
Zuletzt bearbeitet von freakC++ am 12:52:18 11.01.2012, insgesamt 1-mal bearbeitet |
|
 |
icarus2
Mitglied
Benutzerprofil
Anmeldungsdatum: 20.09.2009
Beiträge: 1163
|
icarus2 Mitglied
13:01:41 11.01.2012 Titel: |
|
Zitieren |
Es braucht dort einen expliziten Cast, weil es ein Downcasting ist. Da Java eine typsichere Sprache ist wird verlangt, dass explizit gecastet wird. Es wird verlangt weil das Downcasten gefaehrlich ist, denn Object o koennte gar nicht von der Klasse A erben und dann wuerde der Cast eine Exception ausloesen. Deswegen brauchst du das if instanceof, dann weisst du, dass du es machen kannst. Da der Ausdruck allerdings nicht zur Compile Time sondern zur Laufzeit ausgewertet wird, kann das der Compiler nicht ueberpruefen. Deswegen expliziter cast.
*Edit
Wenn der Compiler intelligent waere, dann wurde es wohl ohne diese expliziten Casts gehen. Aber das koennen Compiler nicht. |
|
|
|
 |
LordJaxom
Mitglied
Benutzerprofil
Anmeldungsdatum: 23.11.2005
Beiträge: 5553
|
LordJaxom Mitglied
13:52:57 11.01.2012 Titel: |
|
Zitieren |
| icarus2 schrieb: | | Wenn der Compiler intelligent waere, dann wurde es wohl ohne diese expliziten Casts gehen. Aber das koennen Compiler nicht. |
Sowas ist IMHO auch nicht die Aufgabe des Compilers, sondern der statischen Codeanalyse, falls vorhanden. Wenn entsprechende Tools mitlaufen, bekäme man ohne vorherige Abfrage bei dem Cast eine Warnung "Possible ClassCastException", mit der if-Abfrage jedoch nicht. |
|
|
|
 |
freakC++
Mitglied
Benutzerprofil
Anmeldungsdatum: 26.04.2008
Beiträge: 1747
|
freakC++ Mitglied
16:56:53 11.01.2012 Titel: |
|
Zitieren |
Hallo zusammen,
ich bin auf noch ein Problem gestossen, das eventuell etwas mit "instanceof" zu tun hat. Daher schreibe ich einfach mal in diesem Thread weiter.
Es geht um folgendes:
Ich habe drei Klassen A, B und C.
| C/C++ Code: | 1 2 3 4 5 6 7 8 9 10 11 12 13 | 1 2 3 4 5 6 7 8 9 10 11 12 13 | public abstract class A {
//...
}
public class B extends A {
//..
public int eineVariable;
}
public class C extends A {
//..
public int andereVariable;
}
| |
| C/C++ Code: | 1 2 3 4 5 6 7 8 9 10 11 12 13 | public abstract class A {
//...
}
public class B extends A {
//..
public int eineVariable;
}
public class C extends A {
//..
public int andereVariable;
}
| |
| C/C++ Code: | 1 2 3 4 5 6 7 8 9 10 11 12 13 | public abstract class A {
//...
}
public class B extends A {
//..
public int eineVariable;
}
public class C extends A {
//..
public int andereVariable;
}
| |
Jetzt habe ich eine komplett unabhängige Methode, die außerhalb aller Klassen liegt. Diese Methode bekommt als Parameter eine Instanz der Klasse A.
| Code: | public void machWas(A myInstanz) {
//...
}
| |
| Code: | public void machWas(A myInstanz) {
//...
}
| |
| Code: | public void machWas(A myInstanz) {
//...
}
| |
Jetzt habe ich folgendes Problem. Wenn es sich bei "myInstanz" um ein Objekt der Klasse B handelt, so möchte ich den Wert von "eineVariable" ausgeben. Wenn "myInstanz" jedoch ein Objekt von C ist, so möchte ich "andereVariable" ausgeben.
Wie mache ich das?
Ich danke euch
lg, freakC++ |
_________________ Gdzie jest mój pstrąg?
Zuletzt bearbeitet von freakC++ am 16:57:48 11.01.2012, insgesamt 1-mal bearbeitet |
|
 |
icarus2
Mitglied
Benutzerprofil
Anmeldungsdatum: 20.09.2009
Beiträge: 1163
|
icarus2 Mitglied
17:11:27 11.01.2012 Titel: |
|
Zitieren |
Ungefaehr so:
| Java Code: | if (myIntance instanceof B) {
// Mach etwas
}
else if (myInstance instanceof C) {
// Mach etwas
}
| |
| Java Code: | if (myIntance instanceof B) {
// Mach etwas
}
else if (myInstance instanceof C) {
// Mach etwas
}
| |
| Java Code: | if (myIntance instanceof B) {
// Mach etwas
}
else if (myInstance instanceof C) {
// Mach etwas
}
| |
|
|
|
|
 |
_kermit
Mitglied
Benutzerprofil
Anmeldungsdatum: 24.01.2011
Beiträge: 74
|
_kermit Mitglied
17:11:41 11.01.2012 Titel: |
|
Zitieren |
| freakC++ schrieb: |
Ich habe drei Klassen A, B und C.
| C/C++ Code: | 1 2 3 4 5 6 7 8 9 10 11 12 13 | 1 2 3 4 5 6 7 8 9 10 11 12 13 | public abstract class A {
//...
}
public class B extends A {
//..
public int eineVariable;
}
public class C extends A {
//..
public int andereVariable;
}
| |
| C/C++ Code: | 1 2 3 4 5 6 7 8 9 10 11 12 13 | public abstract class A {
//...
}
public class B extends A {
//..
public int eineVariable;
}
public class C extends A {
//..
public int andereVariable;
}
| |
| C/C++ Code: | 1 2 3 4 5 6 7 8 9 10 11 12 13 | public abstract class A {
//...
}
public class B extends A {
//..
public int eineVariable;
}
public class C extends A {
//..
public int andereVariable;
}
| |
Jetzt habe ich eine komplett unabhängige Methode, die außerhalb aller Klassen liegt. Diese Methode bekommt als Parameter eine Instanz der Klasse A.
| Code: | public void machWas(A myInstanz) {
//...
}
| |
| Code: | public void machWas(A myInstanz) {
//...
}
| |
| Code: | public void machWas(A myInstanz) {
//...
}
| |
Jetzt habe ich folgendes Problem. Wenn es sich bei "myInstanz" um ein Objekt der Klasse B handelt, so möchte ich den Wert von "eineVariable" ausgeben. Wenn "myInstanz" jedoch ein Objekt von C ist, so möchte ich "andereVariable" ausgeben.
Wie mache ich das? |
Kannst es natürlich mit instanceof lösen:
| Java Code: | 1 2 3 4 5 6 7 8 9 | 1 2 3 4 5 6 7 8 9 | public void machWas(A myInstanz) {
if(myInstanz instanceof B) {
int wert = ((B) myInstanz).eineVariable;
} else if(myInstanz instanceof C) {
int wert = ((C) myInstanz).andereVariable;
}
// irgendwas mit wert
} | |
| Java Code: | 1 2 3 4 5 6 7 8 9 | public void machWas(A myInstanz) {
if(myInstanz instanceof B) {
int wert = ((B) myInstanz).eineVariable;
} else if(myInstanz instanceof C) {
int wert = ((C) myInstanz).andereVariable;
}
// irgendwas mit wert
} | |
| Java Code: | 1 2 3 4 5 6 7 8 9 | public void machWas(A myInstanz) {
if(myInstanz instanceof B) {
int wert = ((B) myInstanz).eineVariable;
} else if(myInstanz instanceof C) {
int wert = ((C) myInstanz).andereVariable;
}
// irgendwas mit wert
} | |
Schöner wäre es, die Methode zu überladen.
| Java Code: | 1 2 3 4 5 6 7 8 9 10 11 | 1 2 3 4 5 6 7 8 9 10 11 | public void machWas(B myInstanz) {
irgendwasMitWert(myInstanz.eineVariable);
}
public void machWas(C myInstanz) {
irgendwasMitWert(myInstanz.andereVariable);
}
public void irgendwasMitWert(int wert) {
// ...
}
| |
| Java Code: | 1 2 3 4 5 6 7 8 9 10 11 | public void machWas(B myInstanz) {
irgendwasMitWert(myInstanz.eineVariable);
}
public void machWas(C myInstanz) {
irgendwasMitWert(myInstanz.andereVariable);
}
public void irgendwasMitWert(int wert) {
// ...
}
| |
| Java Code: | 1 2 3 4 5 6 7 8 9 10 11 | public void machWas(B myInstanz) {
irgendwasMitWert(myInstanz.eineVariable);
}
public void machWas(C myInstanz) {
irgendwasMitWert(myInstanz.andereVariable);
}
public void irgendwasMitWert(int wert) {
// ...
}
| |
Eventuell wäre das aber auch ein Zeitpunkt, dein Design zu überdenken. |
|
|
|
 |
freakC++
Mitglied
Benutzerprofil
Anmeldungsdatum: 26.04.2008
Beiträge: 1747
|
freakC++ Mitglied
17:13:13 11.01.2012 Titel: |
|
Zitieren |
Das würde aber bedeuten, dass ich alle meine Klassen kennen muss, um diese if Abfrage zu erstellen. Was ist aber wenn ich 100 Klassen habe, die von A erben und jeweils eigene Attribute haben?
Kann man das auch schöner lösen?
Danke dir |
_________________ Gdzie jest mój pstrąg?
|
|
 |
icarus2
Mitglied
Benutzerprofil
Anmeldungsdatum: 20.09.2009
Beiträge: 1163
|
icarus2 Mitglied
17:16:12 11.01.2012 Titel: |
|
Zitieren |
| freakC++ schrieb: | Das würde aber bedeuten, dass ich alle meine Klassen kennen muss, um diese if Abfrage zu erstellen. Was ist aber wenn ich 100 Klassen habe, die von A erben und jeweils eigene Attribute haben?
Kann man das auch schöner lösen?
Danke dir |
Dann ist es an der Zeit ein neues Design zu suchen.
Kommt etwas darauf an was du genau machen moechtest. Aber eventuell waere es nicht schlecht eine abstrakte Methode in der Basisklasse zu deklarieren und diese in den Subklassen zu ueberladen.
Oder sich ueberlegen ob diese einzelnen Klassen ueberhaupt eine sinnvolle gemeinsame Basisklasse besitzten.
*Edit
Was moechtest du denn konkret haben? |
Zuletzt bearbeitet von icarus2 am 17:16:51 11.01.2012, insgesamt 1-mal bearbeitet |
|
 |
LordJaxom
Mitglied
Benutzerprofil
Anmeldungsdatum: 23.11.2005
Beiträge: 5553
|
LordJaxom Mitglied
17:47:45 11.01.2012 Titel: |
|
Zitieren |
Spendiere A eine abstrakte Methode "getVariable" und gib in den abgeleiteten Klassen den passenden Wert zurück. |
|
|
|
 |