Registrierung Kalender Mitgliederliste Teammitglieder Suche Häufig gestellte Fragen Zur Startseite

Informatiker Board » Themengebiete » Praktische Informatik » Algorithmen » Leere Oberklasse sinnvoll? » Hallo Gast [Anmelden|Registrieren]
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | An Freund senden | Thema zu Favoriten hinzufügen
Neues Thema erstellen Antwort erstellen
Zum Ende der Seite springen Leere Oberklasse sinnvoll?
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
Haevelin
Tripel-As


Dabei seit: 04.06.2013
Beiträge: 221

Leere Oberklasse sinnvoll? Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Wenn ich eine Klasse Rechteck und eine Klasse Kreis habe, und ich möchte die Objekte, die ich hiervon erstelle in eine ArrayList in Java speichern, so bin ich so vorgegangen, dass ich eine leere Klasse Figur kreiiert habe, Rechteck und Kreis davon erben lasse, und in die ArrayList<Figur> figur alle Elemente von Rechteck und Kreis geschrieben habe. Später dann die Abfrage mit bspw. figur instanceof Rechteck durchführen, um zu entscheiden, was mit der konkreten Figur weiter zu geschehen hat.
Das Figur dabei eine leere Klasse ist, scheint nicht zu stören? Es hat also Sinn leere Klasse als Superklasse zu definieren!
public class Figur {
}

public class Rechteck extends Figur {
double seiteA, seiteB;
....
}

Was ist von diesen Ideen zu halten?
26.03.2014 15:11 Haevelin ist offline Beiträge von Haevelin suchen Nehmen Sie Haevelin in Ihre Freundesliste auf
as_string as_string ist männlich
Haudegen


Dabei seit: 06.11.2013
Beiträge: 638
Herkunft: Heidelberg

RE: Leere Oberklasse sinnvoll? Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Zitat:
Original von Haevelin
Später dann die Abfrage mit bspw. figur instanceof Rechteck durchführen, um zu entscheiden, was mit der konkreten Figur weiter zu geschehen hat.

Das solltest Du nach Möglichkeit nicht machen! Wenn Du eine Methode von einer dieser Figuren aufrufst, dann wird eine gleichnamige Methode in der konkreten Unterklasse aufgerufen werden. So unterschiedest Du, nicht durch ein "instanceof" (Ausnahmen bestätigen die Regel...). So was nennt man dann auch Polymorphy.
Die Idee ist: wenn Du z. B. eine Methode "zeichne()" hast, dann soll das Rechteck wissen, wie das geht für ein Rechteck, und ein Kreis für einen Kreis, mit den jeweiligen Daten, die ein Rechteck oder ein Kreis hat. Deshalb soll es genau darin definiert sein und Du sollst sagen können: "Hier habe ich eine Liste von Figuren, die entweder Kreise oder Rechtecke sein können. Ich will die alle zeichnen, also sag ich denen allen, weil die es wissen, was sie tun müssen!" Das "instanceof" macht Java dann quasi automatisch!

Zitat:
Original von Haevelin
Das Figur dabei eine leere Klasse ist, scheint nicht zu stören? Es hat also Sinn leere Klasse als Superklasse zu definieren!
public class Figur {
}

public class Rechteck extends Figur {
double seiteA, seiteB;
....
}

Was ist von diesen Ideen zu halten?

Ja, das macht man dann allerdings als sogenannte "abstract" Oberklasse. Dann schreibst Du rein, welche Funktionen es geben muss für alle Klassen die diese beerben, ohne einen Funktionsblock wirklich schreiben zu müssen, weil es nur abstrakt deklariert ist. Dafür kannst Du dann nur Objekte von den abgeleiteten Klassen instanziieren, aber nicht von der abstrakten. Aber das ist ja auch sinnvoll, oder?

In Java wäre noch zu überlegen, ob Du es nicht vielleicht als Interface deklarierst.

Gruß
Marco
26.03.2014 15:25 as_string ist offline E-Mail an as_string senden Beiträge von as_string suchen Nehmen Sie as_string in Ihre Freundesliste auf
Haevelin
Tripel-As


Dabei seit: 04.06.2013
Beiträge: 221

RE: Leere Oberklasse sinnvoll? Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Besser, wenn ich meinen funktionierenden Code einmal angebe:

1) Die Klasse Objekt

public class Objekt {

}

2) Die erbenden Klassen Rechteck und Kreis

public class Rechteck extends Objekt {
private double seitenlaenge;

public Rechteck(double laenge) {
this.seitenlaenge = laenge;
}

public double flaeche() {
return seitenlaenge * seitenlaenge;
}
}



public class Kreis extends Objekt {
private double radius;

public Kreis(double radius) {
this.radius = radius;
}

public double flaeche() {
return radius * 2 * Math.PI;
}

}


3) Die Testklasse

import java.util.ArrayList;

public class TestObjekt {

public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayList<Objekt> liste = new ArrayList<Objekt>();
Rechteck r1 = new Rechteck(2.0);
liste.add(r1);
Rechteck r2 = new Rechteck(3.0);
liste.add(r2);
Kreis k1 = new Kreis(2.0);
liste.add(k1);
Kreis k2 = new Kreis(3.0);
liste.add(k2);
for (Objekt k : liste) {
if (k instanceof Rechteck) {
System.out.println(((Rechteck) k).flaeche());

}
if (k instanceof Kreis) {
System.out.println(((Kreis) k).flaeche());
}
}
}

}
26.03.2014 16:12 Haevelin ist offline Beiträge von Haevelin suchen Nehmen Sie Haevelin in Ihre Freundesliste auf
as_string as_string ist männlich
Haudegen


Dabei seit: 06.11.2013
Beiträge: 638
Herkunft: Heidelberg

Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Ich kann leider erst drüber schauen, wenn ich zu Hause bin... Ich melde mich dann heute Abend.
Aber schau mal im Internet nach "java abstract super class" oder ähnliches. Da solltest Du vieles Interessantes dazu finden können!

Gruß
Marco
26.03.2014 16:29 as_string ist offline E-Mail an as_string senden Beiträge von as_string suchen Nehmen Sie as_string in Ihre Freundesliste auf
as_string as_string ist männlich
Haudegen


Dabei seit: 06.11.2013
Beiträge: 638
Herkunft: Heidelberg

Auf diesen Beitrag antworten Zitatantwort auf diesen Beitrag erstellen Diesen Beitrag editieren/löschen Diesen Beitrag einem Moderator melden       Zum Anfang der Seite springen

Hallo!

Nein, das macht man etwas anders. Die Oberklasse ist nicht wirklich komplett leer, sondern definiert den Umfang an Methoden, die Du auf jeden Fall von jeder abgeleiteten Klasse erwartest, egal welche konkrete Ausprägung sie darstellt.

Du möchtest in Deinem Beispiel ja offenbar, dass beide Unterklassen einen Flächeninhalt ausgeben können. Das ist also eine Methode, die ein "Ding" von der Art "Figur" auf jeden Fall unterstützen muss (jetzt hast Du das "Objekt" genannt, aber das finde ich gar nicht gut, weil es in Java schon ein "Object" gibt, von dem automatisch jede Klasse erbt und Dein "Objekt" vom Namen her dann ja auch nichts aussagt. Bleiben wir lieber bei "Figur"!).

Weil Du aber in der Oberklasse diese Funktion noch gar nicht ausimplementieren kannst, machst Du eine abstrakte Oberklasse namens Figur, etwa so:
code:
1:
2:
3:
public abstract class Figur {
	public abstract double flaeche();
}


Dann sehen die zwei abgeleiteten Klassen so aus (ich habe die eine nicht Rechteck, sondern Quadrat genannt, da ja offenbar jede Seite die selbe Länge haben soll...)
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
public final class Quadrat extends Figur {
	private double seitenlaenge = 0.0;

	public Quadrat(double seitenlaenge) {
		super();
		this.seitenlaenge = seitenlaenge;
	}

	@Override
	public double flaeche() {
		return seitenlaenge * seitenlaenge;
	}

}


public final class Kreis extends Figur {
	private double radius = 0.0;

	public Kreis(double radius) {
		super();
		this.radius = radius;
	}

	@Override
	public double flaeche() {
		return Math.PI * radius * radius;
	}

}

Übrigens ist die Kreisfläche immer noch pi*r^2 und nicht 2pi * r, was der Umfang wäre!
Ich habe bei mir jetzt immer noch den super()-Konstruktor aufgerufen. Das kannst Du natürlich weg lassen in diesem Fall, weil die Super-Klasse gar keinen Konstruktor hat (bis jetzt...).

Dann kannst Du nämlich ganz ohne das instanceof if/switch-Verhauen und cast-Orgien leben:
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
import java.util.ArrayList;

public class polymorphy_test {

	public static void main(String[] args) {
		ArrayList<Figur> liste = new ArrayList<>();
		Quadrat r1 = new Quadrat(2.0);
		liste.add(r1);
		Quadrat r2 = new Quadrat(3.0);
		liste.add(r2);
		Kreis k1 = new Kreis(2.0);
		liste.add(k1);
		Kreis k2 = new Kreis(3.0);
		liste.add(k2);
		for (Figur k : liste) {
			System.out.println(k.flaeche());
		}
	}

}


Ich habe wieder etwas umbenannt... Aber siehst Du wie einfach plötzlich die for-Schleife wird?
Noch viel, viel wichtiger ist aber: Normalerweise hast Du ja eine Liste von Figur-Objekten irgendwie generiert, vielleicht Daten aus einer Datei gelesen oder einen Benutzer eingeben lassen. Jetzt willst Du immer von der ganzen Liste die Flächen ausgeben, dann genügt diese kurze For-Schleife. Wenn Du irgendwann mal eine neue Figur machen willst, z. B. ein echtes Rechteck, das Länge und Breite hat, dann genügt es eine solche Klasse zu machen und von Figur erben zu lassen. Du musst dann nur Objekte diesen neuen Typs in das Array rein bringen und schon funktioniert Deine for-Schleife völlig ohne Änderung.

Mit Deiner Technik würde das nicht gehen. Wenn Du eine neue Klasse machst und die in Dein Array packen wolltest, müsstest Du auch in jeder for-Schleife, die alle Objekte bearbeiten will, immer ein "if(k instanceof blabla)..." rein schreiben.

Wenn Du objektorientiert programmierst und Du hast solche if/switch-Blöcke in Deinem Code, dann ist das normalerweise ein Zeichen für eine schlechte Vererbungshierarchie und schlechte Ausnutzung der Polymorphie!

Gruß
Marco

PS: In diesem Fall hätte ich unter Java eher ein Interface benutzt!

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von as_string: 26.03.2014 22:53.

26.03.2014 22:53 as_string ist offline E-Mail an as_string senden Beiträge von as_string suchen Nehmen Sie as_string in Ihre Freundesliste auf
Baumstruktur | Brettstruktur
Gehe zu:
Neues Thema erstellen Antwort erstellen
Informatiker Board » Themengebiete » Praktische Informatik » Algorithmen » Leere Oberklasse sinnvoll?