Neue Antwort schreiben 
 
Themabewertung:
  • 0 Bewertung(en) - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
[geteilt] C-Diskussion
PacMani
Unregistered

 
Beitrag #41
RE: Der Unnötige Informationen Thread
Warum sollte ich nicht alles static machen?
Es gibt sogar eine Regel, die besagt, dass man rein garnichts static machen sollte.
Der Sinn dahinter ist die Erweiterbarkeit. Vielleicht willst du am Anfang nur einen Spieler in deinem Pacman-Klon haben - aber später wird daraus ein Multiplayergame, und dann darf die Klasse nicht mehr static sein.
Klar, wenn du fest weißt, dass nur ein Spieler im Spiel ist, kannst du die Klasse static machen.
Aber selbst hier hast du das Problem, dass ein Spieler dann immer irgendwie da ist. Wenn du eine neue Spielrunde starten willst, verwirfst du nicht einfach die alte Spieler-Instanz und erstellst eine neue - das geht ja nicht, da static. Du müsstest eine unnötige Methode wie "Reset()" implementieren, die den Spieler auf die Standardwerte zurücksetzt. Du müsstest alle internen Listen und Variablen, die der Spieler benutzt hat, auf einen Ausgangszustand wiederherstellen. Diese Arbeit brauchst du nicht manuell machen - nutze eine neue Instanz einer nicht-statischen Klasse und schmeiß die alte Weg. Du radierst ja auch nicht ein Papier sauber, nur weil du ein neues brauchst.

Warum sollte ich nicht alles public machen?
Der Sinn hier hinter liegt einfach im Verstecken von Implementierungsdetails für die Programmierer, die deine Klasse nutzen.
Die Programmierer sollen nur die Methoden sehen, die auch wichtig für sie sind - interne Abläufe der Klasse haben sie garnichts anzugehen.
Z.B. würdest du einen große öffentliche Methode in mehrere kleine aufteilen (besonders wenn sich die Abläufe wiederholen) und diese kleinen nicht public machen, da sie einzeln aufgerufen keinen Sinn ergeben. Eine übersichtliche Klasse erfreut jeden Programmierer.
Eine Bedienungsanleitung für Windows zeigt auch nur, wie man was benutzt, und nicht, wie der Kernel dahinter die Sachen erledigt.

Warum brauche ich Inheritance wenn ich auch einfach ein Feld machen kann mit der Superklasse und darauf die Methoden aufrufen?
Ein Hund ist ein Säugetier. Ein Hund besitzt kein Säugetier.
Ersteres drückst du durch Vererbung aus. Zweites (die so genannte Komposition) durch ein Feld. Zweites hat keinen Sinn.
Weiterhin müsstest du ganzschön geschachtelt denken, wenn du mehrere Ebenen der Vererbung hast. Stell dir mal vor, jemand will einen Hund im Programm umbringen. Jedes Lebewesen kann umgebracht werden. Also müsste er anstatt einfach Hund.Kill() den Code Hund.Säugetier.Lebewesen.Kill() schreiben.
Und nur ersteres drückt direkt und einfach aus, dass du den Hund umbringen willst. Warum es also dem anwenden Programmierer unnötig kompliziert machen.

Warum geht Inheritance nur mit einer Klasse?
Ehrlich gesagt habe ich mich das auch schon oft gefragt. Es ist auch nicht in allen Sprachen Vorschrift: in C++ hast du z.B. diese Möglichkeit - aber selbst dort wird es stark beschimpft: Das Problem bei Mehrfachvererbung ist unter vielen anderen einfach das, dass zwei Basisklassen gleichnamige Felder beinhalten können und diese zu Konflikten in der erbenden Klasse führen würden. Weiterhin willst du mit Mehrfachvererbung eher eine "hat-ein/eine" Beziehung ausdrücken, und nicht "ist ein/eine" . Dann solltest du auf Felder zurückgreifen. Mir fällt mittlerweile garkein "sinnvolles" Beispiel für Mehrfachvererbung ein, weil ich so nicht mehr denke. Kannst du mir eins geben? In C# kann man immerhin mehrere Schnittstellen neben einer Klasse implementieren, aber Schnittstellen sind halt keine Klasse - sie würden vermutlich trotzdem deinen Implementierungswünschen näher kommen.

Wozu brauche ich Konstruktoren, kann ich nicht einfach eine init()-Methode machen?
Bei Konstruktoren ist sichergestellt, dass der Code darin für die neue Instanz definitiv ausgeführt wurde. Bei Init-Methoden hast du diese Gewährleistung nicht. So hast du in der Klasse Hund die Variable Bein, und du musst erst eine neue Instanz von Bein erstellen, bevor du auf Methoden davon zugreifen kannst. Erstellst du also erst eine Instanz von Hund ohne Konstruktorcode und willst dann auf das Bein zugreifen, kriegst du ne Exception, weil das Bein noch garnicht erstellt wurde. Oh, da hat mal wieder jemand Init vergessen. Unsinn allerdings, da ein Hund ohne "fertige" Beine garnicht existieren kann (wenn du sowas brauchst erstelle eine Klasse "Missgeburt" :P). Weiterhin sparst du dir eine Zeile Code.
Bei statischen Klassen hat so etwas wie Init Sinn. Du kannst ja garkeine Instanz von statischen Klassen erstellen. Ggf. benötigen bestimmte Variablen aber einen Ausgangswert in den statischen Klassen, und der wird in Init gesetzt. Oft kapselt man das aber beim Zugriff auf die gefragte Variable, also z.B. in einer C# Property wie hier:
Code:
private static Bein _bein1;

public static Bein Bein1
{
    get
    {
        if (_bein1 == null)
        {
            _bein1 = new Bein();
        }
        return _bein1;
    }
}

bzw. in Java würdest du es (wie immer umständlich) mit einem getter machen:

Code:
private static Bein _bein1;

public static Bein getBein1 {
    if (_bein1 == null) {
        _bein1 = new Bein();
    }
    return _bein1;
}
In C++ nutzt du Konstruktoren oft, um den Speicher zu "nullen", da bei vielen Compilern nur die Speicherstelle der Instanz hinterlegt wird, dort aber noch Müll von vorherigen Verwendungen liegen kann. Wenn du hier deinen Konstruktor leer lässt und mal Init vergisst und dann auf Dinge zugreifst, konnte das früher noch in schönen Systemabstürzen enden (mal die Adresse von X auslesen, oh Init vergessen, oh die Adresse ist zufälliger Speichermüll, da schreib ich mal rein, oh Zugriffsverletzung, oh Bluescreen, oh Neustart, oh ich nutz demnächst einen Konstruktor).

Was sollte ich dann in den Konstruktor packen und was in Methoden?
Ich glaube das sollte obige Antwort beantworten. Alles, was definitiv ausgeführt sein muss, bevor du weitere Fummeleien mit der Objektinstanz machst kommt in den Konstruktor. Der ist im Endeffekt bei C# übrigens auch nur ne Methode namens "ctor(...)", die der Compiler erstellt.

Ganz abgesehen davon wenn man mal generics braucht, die sind konstruktionsbedingt in Java irre.
Keine Ahnung, kenne keine Generics in Java, wenn die aber so poorly asses implementated sind wie die restlichen nachträglichen Neuerungen... in C# sind die simpelpimpel.
Code:
public class KlasseMitIrgendeinemWert<T>
{
    private T _wert;

    public KlasseMitIrgendeinemWert<T>(T wert)
    {
        _wert = wert;
    }

    public T Wert
    {
        get { return _wert; }
        set { _wert = value; }
    }
}

public static class Program
{
    public static void Main(string[] argsDieJederIgnoriert)
    {
        KlasseMitIrgendeinemWert<int> dieIntKlasse = new KlasseMitIrgendeinemWert<int>(32);

        // Und genau hier hast du Typensicherheit. Hättest du eine Klasse ohne Generics, die stattdessen
        // nur ein Objekt verwaltet, müsstest du erst per Hand in einen int casten.
        if (dieIntKlasse.Wert == 32)
        {
            Console.WriteLine("EUDA BIN ICH GEUL DA!!!");
        }
    }
}
Ersetze T also immer gedanklich durch den Datentyp, den du in der Instanzierung festgelegt hast.
15.12.2012 17:32
Diese Nachricht in einer Antwort zitieren
oreissig Offline
Maître Modérateur

Beiträge: 12.021
Registriert seit: Jul 2008
Beitrag #42
RE: [geteilt] C-Diskussion
[ ] ihr habt verstanden, dass heinze nur fragen gestellt hat, um zu zeigen, dass die materie nicht so einfach ist
15.12.2012 17:37
Webseite des Benutzers besuchen Alle Beiträge dieses Benutzers finden Diese Nachricht in einer Antwort zitieren
PacMani
Unregistered

 
Beitrag #43
RE: [geteilt] C-Diskussion
[ ] du hast nicht alle seine posts vollständig gelesen
15.12.2012 17:38
Diese Nachricht in einer Antwort zitieren
oreissig Offline
Maître Modérateur

Beiträge: 12.021
Registriert seit: Jul 2008
Beitrag #44
RE: [geteilt] C-Diskussion
doch, aber ich finds sinnlos hier in gigantopostings über quatsch zu reden, der nich thema is. außerdem wird dabei regelmäßig gefailt
15.12.2012 17:40
Webseite des Benutzers besuchen Alle Beiträge dieses Benutzers finden Diese Nachricht in einer Antwort zitieren
TAL Offline
機関車

Beiträge: 6.342
Registriert seit: Jul 2008
Beitrag #45
RE: Der Unnötige Informationen Thread
(15.12.2012 17:18)oreissig schrieb:  ...
das "spart Zeilen"-argument ist quatsch, du könntest auch eine methode setAllData("foorious", 1.89) machen und das in einem rutsch setzen, trotzdem hat der Konstruktur eine andere Semantik, denn er kann nur 1x aufgerufen werden im gegensatz zu set-methoden, mit denen man so sachen auch während des Lebenszykluses eines Objektes ändern kann, was aber u.U. gar nicht erwünscht ist

public Patient(String patientenNummer, Map<String, Object> restlicheParameter) {...}*
:trollface:


*: Für Java <5 kompatibilität

(Dieser Beitrag wurde zuletzt bearbeitet: 15.12.2012 18:07 von TAL.)
15.12.2012 17:40
Alle Beiträge dieses Benutzers finden Diese Nachricht in einer Antwort zitieren
PacMani
Unregistered

 
Beitrag #46
RE: [geteilt] C-Diskussion
(15.12.2012 17:40)oreissig schrieb:  doch, aber ich finds sinnlos hier in gigantopostings über quatsch zu reden, der nich thema is. außerdem wird dabei regelmäßig gefailt

machen dir zu viele buchstaben zu schaffen?
15.12.2012 18:57
Diese Nachricht in einer Antwort zitieren
Neue Antwort schreiben 


Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste