Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

11

16.11.2014, 17:53

Weil der Code je nach Subklasse anders sein soll. Daher soll die CollisionObject-Klasse und assignShape-Methode abstrakt sein.
Das ist aber Quatsch. Wozu sollte eine Basis-Klasse vorgeben, wie eine davon abgeleitete Klasse konstruiert/initialisiert werden muss? Das sollte die abgeleitete Klasse doch selbst viel besser wissen. Daher ist eine abstrakte Methode als Aufruf im Konstruktor Unfug. Entweder die abgeleitete Klasse braucht so einen Aufruf und implementiert ihn ohnehin selbst oder sie braucht ihn nicht, womit die Methode überflüssig wäre. In beiden Fällen ist die abstrakte Methode daher nicht notwendig und verursacht im schlimmsten Fall schwerste Abstürze des Programms (zumindest aus User-Sicht wäre das schlimm, aus Entwickler-Sicht wäre das noch der günstigste Fehlerfall), weil eine Methode einer abgeleiteten Klasse gerufen wird, obwohl die Instanz dieser Klasse noch gar nicht initialisiert werde konnte.
Beispiel: CollisionRect erbt von CollisionObject und braucht im Konstrktur die Werte für Länge und Breite. Diese Werte kann die "assignShape"-Methode aber nicht verwenden, weil sie vom Konstruktor noch nicht verarbeitet werden konnten, da dieser erst nach der assignShape-Methode überhaupt gerufen wird. Was genau soll "assignShape" jetzt tun? Die Werte raten? Falsche Werte verwenden? Abstürzen?
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »BlueCobold« (16.11.2014, 17:58)


12

16.11.2014, 18:26

@BlueCobold
Ich glaube ich habe das ganze ein bisschen falsch erklärt.

In meinem Falle ist "assignShape" ein simpler getter beziehungsweise setter, je nachdem wie die Methode am Ende nun aussieht. Die Klasse CollisionObject enthält eine Variable. Diese soll je nach Subklasse anders aussehen; Allerdings soll der Entwickler der Subklasse sich nicht daran erinnern müssen die Variable selber zu initialisieren, sondern er wird dazu aufgefordert (Muss also) eine abstrakte Methode der Superklasse zu implementieren.
(Da fällt mir auch gerade ein weiterer Fehler in meinem Code vom Startpost ein; assignShape() sollte ein getter sein welcher in der Superklasse benutzt wird. In Java könnte das ganze so aussehen:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
public abstract class CollisionObject {
    Shape shape;
    public CollisionObject(){
        shape = assignShape();
    }
    public abstract Shape assignShape(); //Sollte eigentlich getShape heißen, aber da ich das ganze jetzt schon so angefangen habe nenne ich es jetzt nicht um
}
public class CollisionRect extends CollisionObject {
    public Shape assignShape(){return new Shape(blabla);} //MUSS implementiert werden
}
//!\\ Bei Initialisierung von einem CollisionRect wird nun der Konstruktor von CollisionRect Aufgerufen, und implizit auch der von CollisionObject; In diesem wird nun assignShape() von CollisionRect der Variable zugewiesen, was eine NPE vermeiden wird.

Klar, ich könnte einfach eine Shape im Konstrukor per CollisionRect : CollisionObject(dieShape) mitgeben, aber es geht hier eher ums Prinzip falls es doch mal etwas komplizierter sein muss.

Ich hoffe ich konnte mich etwas klarer ausdrücken und habe deinen Post nicht komplett missverstanden.

MfG
Darkium

13

16.11.2014, 18:35

Dann ruft die abgeleitete klasse explizit den konstruktor der basisklasse auf und übergibt dieser sein wasauchimmer.

Sacaldur

Community-Fossil

Beiträge: 2 301

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

14

16.11.2014, 20:47

Man kann es auch so erklären: virtuelle (bzw. in anderen Sprachen abstrakte) Methoden verlangen von den jeweiligen Implementierungen, dass auf jeden Fall ein bestimmtes Verhalten implementiert werden muss. In deinem Fall braucht die Basisklasse ja eigentlich kein bestimmtes Verhalten, sondern Daten, die die Form (Shape) beschreiben. Diese können per Parameter an den Konstruktor übergeben werden, was bereits aufgezeigt wurde.

Eine andere Frage: warum sollte es für unterschiedliche Shapes unterschiedliche Ausprägungen von "CollisionObject" geben? Wenn der einzige Unterschied zwischen den Ausprägungen die Form ist, dann solltest du bei einer einzigen Klasse für die CollisionObjects bleiben und die Shape per Parameter entgegen nehmen (siehe "composition over inheritance"). Wenn du dir das erzeugen von bestimmten Formen vereinfachen willst, kannst du auch andere Vorgehensweisen wählen, wie Funktionen, die statt der entsprechenden Konstruktoren aufgerufen werden. (Wenn man sich dabei an Entwurfsmuster halten will, gibt es dafür bspw. die Factory Method oder die Abstract Factory.)
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

15

16.11.2014, 21:04

@Sacaldur

Der Code ist nur ein Beispiel. Es geht eher um die Annahme dass ich in einer Situation bin wo man nicht einfach ein Argument an den Konstruktor geben kann um das Problem zu lösen & dass es weitere Unterschiede zwischen den verschiedenen Subklassen von CollisionObject gibt (Welche es auch geben wird). Aus zwei Gründen: Erstens weil mich es eben interessiert die Lösung für so ein Problem zu wissen, und zweitens da sich der Code wie gesagt noch verändern wird.

@Roflo

Klar, das wäre natürlich die einfachste Möglichkeit. Aber wie gesagt, ich will eben wissen wie man es machen würde wenn man in einer komplexeren Situation ist ^^

MfG
Darkium

Sacaldur

Community-Fossil

Beiträge: 2 301

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

16

16.11.2014, 23:08

[...] weil mich es eben interessiert die Lösung für so ein Problem zu wissen [...]

Die Lösung für ein solches Problem wurde bereits genannt.

Solltest du _tatsächlich_ und nicht nur hypothetisch auf eine Situation stoßen, wo du geneigt wärst, so vorzugehen, kannst du ja nochmal nachfragen, wie man es am ehesten lösen könnte. Wenn es an komplexere Dinge geht, solltest du aber auch auf eine single responsibility der einzelnen Komponenten (/Klassen) achten.
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

17

17.11.2014, 06:38

Der Code ist nur ein Beispiel. Es geht eher um die Annahme dass ich in einer Situation bin wo man nicht einfach ein Argument an den Konstruktor geben kann um das Problem zu lösen
Selbst dann lässt es sich nicht über so eine virtual-Konstruktion lösen. Ich habe doch bereits erklärt, wo das Problem liegt.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Werbeanzeige