AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi OOP Problem: änderungen werden nicht übernommen
Thema durchsuchen
Ansicht
Themen-Optionen

OOP Problem: änderungen werden nicht übernommen

Ein Thema von mimi · begonnen am 25. Dez 2005 · letzter Beitrag vom 1. Jan 2006
Antwort Antwort
Seite 1 von 3  1 23      
mimi

Registriert seit: 1. Dez 2002
Ort: Oldenburg(Oldenburg)
2.008 Beiträge
 
FreePascal / Lazarus
 
#1

OOP Problem: änderungen werden nicht übernommen

  Alt 25. Dez 2005, 10:09
Hallo,
Ich habe jetzt etwas viel geschrieben ich hoffe das sich jemmand die mühe macht diese
Frage durchzulesen und eine lösung für das "ausfürhlich" beschriebende problem zu finden *G*
Vielen Dank im voraus.

Ich möchte mir ein eigene "kleine" GUI schreiben.
Die nur ein paar standart komponenten hat wie z.b.
- Button
- Edit
- Formula
ersteinmal, später kann ich sie ja noch erweitern.

Ich habe mir jetzt einige gedanken gemacht für den Klassenaufbau und auch
angefangen da bin ich leider auf unerwartete probleme gestoßen.
Ich möchte ein obj per Create erstellen wie in der "Delphi GUI"
und genau hier fangen die probleme an:
ich wollte eine allgemine komponenten liste erstellen die habe ich
in der Unit definiert:
Delphi-Quellcode:
var
  GUI:TGUI;

implementation
dort sollen alle komponenten rein die mit Create erstellt werden.
TGUI sieht so aus:
Delphi-Quellcode:
  TGUI = class
  private
  public
    items:TObjectList;
    constructor Create;
    procedure Add(obj:TStdObj);
    procedure Del(Index:Integer);
    procedure Draw;
  end;
das Stanadt obj von denn allen abgeleitet werden müssen damit es
funktioniert sieht so aus:

Delphi-Quellcode:
  TSTDObj = class
  private
  public
    GFL:TMyCanvas;
    Sel:TStdObj;
    Namen:String;
    Caption:String; // Enhälst den Anzeige Text
    Hint:String; // Enhälst eine Genaue Beschreibung der Liste
    Parent:String; // Enthälst den Unterkomponente
    Typ1:String; // Benuterdefniert
    Visible:Boolean; // Sichtbar oder unsichtbar
    ShowHint:Boolean; // Beschreibung anzeigen oder nicht anzeigen
    isStdList:Boolean; // Fügt in eine Eigne Liste ein die jede komponente hat
    Typ:Integer; // Benuterdefniert
    x,y,w,h,r:Integer; // Position(x,y) Größe(w,h)
    ObjTyp:Integer; // Kreis oder Rechteck
    absX,AbsY:Integer; // Abstand zum Rand
    onMouseMove:TMouseMove;
    onMouseUp:TMouseUp;
    onMouseDown:TMouseDown;
    onMouseLave:TMouseLave;
    onKeyDown:TKeyDown;
    onKeyPress:TKeyPress;
    onKeyUp:TKeyUp;
    constructor Create(h:HWND;obj:Tobj);
    procedure Draw;

  end;
Jedes obj gehört zu einem Formual ohne gehts nicht:
Delphi-Quellcode:
  TFormula = class(TStdObj)
  private
    MoveT:Integer;
  public
    Titel_W,Titel_H,Titel_X,Titel_Y:Integer;
    f:TForm;
    EnabledColor:TColor;
    constructor Create(Form:TForm; pCaption:String);
    procedure Draw;
    procedure Click(px,py:Integer;Button: TShiftState);
    procedure MoveUp(px,py:Integer;Button: TMouseButton);
  end;

implementation

constructor TFormula.Create(Form:TForm;pCaption:String);
begin
  inherited Create(Form.Handle,self);
  EnabledColor:=clRed;

  f:=Form;
  x:=0; y:=0; w:=form.Width; h:=Form.Height;
  Titel_W:=w; Titel_H:=20; Titel_X:=0; Titel_Y:=0;
  Form.BorderStyle:=bsNone;
  Form.Position:=poDesigned;
  Caption:=pCaption;
  MoveT:=-1;
end; // Create

// aufruf
procedure TForm1.FormCreate(Sender: TObject);
var
  Button:TMyButton;
begin
  f:=TFormula.Create(Form1,'Dies ist ein kleiner test');
  f.namen:='Form1';

  button:=TMyButton.Create(Form1.Handle,button);
  button.Caption:='Hallo';
  button.Namen:='button1';
  button.x:=10;
  button.y:=10;
  Button.w:=10;
  Button.h:=10;


  f.absX:=2;
  f.absY:=2;

end;
Das Problem ist jetzt wenn ich ein variable änder z.b. den Caption wird dies leider nicht in die obj liste übernommen.
und ich möchte gerne das diese auch übernommen werden. d.h. alle variablen die ich änder kann sollen auto. in
die obj liste übernommen werden. ich dachte mir das ein "zeiger" oder was änliches auf das gerade erstelle obj
zeigt. Wie z.b. mit folgedner defniation:
  test:=test3 jetzt wird ja test mit test3 verküpft und so dachte ich mir das in meinem problem auch.
Das ganze soll wie in der Delphi GUI ablaufen. Dachte ich mir.
ich hoffe ihr versteht worauf ich hinaus möchte.

Anmerkung:
ich schreibe zwar schon seit ca 5-7 Jahren in Delphi meine Programme aber mit der OOP
habe ich bis noch nicht so ausführlich gearbeitet d.h. Ich habe schon klassen defniniert
und ereignisse und eigenschaften erstellt nur was ich bis jetzt noch nicht getan habe ist
mit vererbungen zu arbeiten also das "eigentliche" oop.
Michael Springwald
MFG
Michael Springwald,
Bitte nur Deutsche Links angeben Danke (benutzte überwiegend Lazarus)
  Mit Zitat antworten Zitat
jbg

Registriert seit: 12. Jun 2002
3.483 Beiträge
 
Delphi 10.1 Berlin Professional
 
#2

Re: OOP Problem: änderungen werden nicht übernommen

  Alt 25. Dez 2005, 11:30
Dazu rate ich dir mal ein OOP Tutorial durchzulesen. Dann wirst du sehen, dass z.B. die Draw-Methode am besten virtuell sein sollte, und was man unter Information-Hiding versteht. Feld-Deklarationen haben nichts im public-Bereich zu suchen, sondern gehören in den private-Bereich. Im protected unt public-Bereich wird dann per Eigenschaften (=> property) der Zugriff geregelt. So kann man z.B. mit "property Caption: string read FCaption write SetCaption;" auf die Veränderung der Caption mit einem Neuzeichnen reagieren, was mit deinem aktuellen Programmcode nicht geht.


Und nun noch zur Deutschen Sprache:
Die Art zu Stehen hat nichts mit dem Standard zu tun. Warum schreiben eigentlich 70% aller Deutschen das Wort immer falsch. Irgendwas muss da in den Schulen wohl falsch laufen. Vielleicht sollte man der Dudenkommision auch mal die "Art zu Stehen" als alternative für "Standard" vorschlagen.

Auch wenn man in der gesprochenen Sprache bei "Formular" das "r" verschluggt, wird es trotzdem geschrieben
  Mit Zitat antworten Zitat
mimi

Registriert seit: 1. Dez 2002
Ort: Oldenburg(Oldenburg)
2.008 Beiträge
 
FreePascal / Lazarus
 
#3

Re: OOP Problem: änderungen werden nicht übernommen

  Alt 25. Dez 2005, 12:08
Vielen Dank. Das tutor werde ich mir gleich mal durchlesen. evlt. gibt es ja anregungen für die Klassenstrucktur.

Zitat:
Warum schreiben eigentlich 70% aller Deutschen das Wort immer falsch.
schön dann bin ich wenigents mit diesem Problem nicht alleine !
Michael Springwald
MFG
Michael Springwald,
Bitte nur Deutsche Links angeben Danke (benutzte überwiegend Lazarus)
  Mit Zitat antworten Zitat
mimi

Registriert seit: 1. Dez 2002
Ort: Oldenburg(Oldenburg)
2.008 Beiträge
 
FreePascal / Lazarus
 
#4

Re: OOP Problem: änderungen werden nicht übernommen

  Alt 25. Dez 2005, 13:48
ich habe mir das Tutor durchgelesen und wollte eine Klassenstruckur schreiben die sieht jetzt so aus. dazu habe ich einige fragen:
Delphi-Quellcode:
unit uStdObj;

interface

type
  TStdObj = class
  private
    FName:String; // Enhält den Namen des Obj
    FCaption:String; // Enhält das was Angezeigt wird
    FTag:Integer; // unBelengt
    Fx:Integer; // die X Position vom OBJ
    Fy:Integer; // die Y Position vom ObJ
    fw:Integer; // Die Breite vom Obj
    Fh:Integer; // die Höhe vom Obj
    procedure SetCaption(Caption:String);
    procedure SetnNmen(Namen:String);
  public
    constructor Create(obj:TStdObj);
    destructor Free;
    procedure Draw
  published
    property Name:string read fName write fName;
    property Caption:string read fCaption write fCaption;
  end;

implementation

constructor TStdObj.Create(obj:TStdObj);
begin
end; // Create

destructor TStdObj.Free;
begin
end; // Free

procedure TStdObj.SetCaption(Caption:String);
begin
  fCaption:=Caption;
  Draw;
end; // SetCaption

procedure TStdObj.SetNamen(Namen:String);
begin
  fNamen:=Namen;
  Draw;
end; // SetNamen

end.
1: Eigenschafen:
Ich möchte gerne das bei jede änderung eine eigenschft die procedure Draw danach ausgeführt wird. Muss ich das denn so "aufwendig" schreiben wie ich das mit namen und Caption gemacht habe, oder kann ich das auch etwas kürtzer schreiben.

2: Strucktur:
Ist die strucktur bis jetzt sinvoller als die "alte" ?
Michael Springwald
MFG
Michael Springwald,
Bitte nur Deutsche Links angeben Danke (benutzte überwiegend Lazarus)
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#5

Re: OOP Problem: änderungen werden nicht übernommen

  Alt 25. Dez 2005, 14:43
Zitat von mimi:
1: Eigenschafen:
Ich möchte gerne das bei jede änderung eine eigenschft die procedure Draw danach ausgeführt wird. Muss ich das denn so "aufwendig" schreiben wie ich das mit namen und Caption gemacht habe, oder kann ich das auch etwas kürtzer schreiben.
Ja, du solltest es genau so machen, wie du es für Caption und Namen gemacht hast. Es ist durchaus sinnvoll das so zu tun, da du unter gewissen Umständen (Die Komponente wird noch viel größer) vielleicht spezielle Parameter übergeben möchtest, nur partiell zeichnet, gar nicht zeichnest (nicht sichtbare Eigenschaften...).

Zitat von mimi:
2: Strucktur:
Ist die strucktur bis jetzt sinvoller als die "alte" ?
Das definitiv. Aber es gibt immer noch ein paar Dinge die ich bemängeln würde. Als erstes mal die Properties, du benutzt jetzt schon richtig Properties und hast auch setter für diese geschrieben, vielleicht solltest du diese auch verwenden!

In den Aufruf des Konstruktors sollte unbedingt immer als erstes ein Aufruf des Vorgänger Konstruktors (analog beim Destruktor).
Und dein Destruktor sollte Destroy heißen (und ein override bekommen). Free solltest du nicht überschreiben, da Free nicht mehr macht als zu schauen ob die Instanz noch existiert (Referenz <> nil) und dann Destroy aufruft.

Wenn dies die Basisklasse ist, von denen andere Objekte abgeleitet werden sollen, dann solltest du zudem darüber nachdenken, die setter lieber protected zu deklarieren (selbes würde ich mit draw machen). Für Draw wäre dann noch interessant wohin du zeichnen lassen möchtest. Ach ja, einige Methoden (hier natürlich nur draw) solltest du in der Basisklasse einfach mal abstract lassen. Ich weiß nicht ob du in deinem Tut auch schon was über Interfaces und abstrakte Klassen gelesen hast, aber die sind in der OOP von hoher Bedeutung, da du mit ihnen sehr viel sehr elegant lösen kannst.

Wie gesagt, dein Ansatz ist schon deutlich besser als der erste, aber ich denke du wirst noch viel lernen (während der Entwicklung). Wichtig ist es halt, möglichst gut vorbereitet zu starten, Fehler vermeiden kostet immer viel viel weniger als welche Nachträglich zu beseitigen.

Gruß Der Unwissende
  Mit Zitat antworten Zitat
mimi

Registriert seit: 1. Dez 2002
Ort: Oldenburg(Oldenburg)
2.008 Beiträge
 
FreePascal / Lazarus
 
#6

Re: OOP Problem: änderungen werden nicht übernommen

  Alt 25. Dez 2005, 14:56
was meisnt du mit "setter" ?

Zitat:
Wichtig ist es halt, möglichst gut vorbereitet zu starten, Fehler vermeiden
das möchte ich dies mal wirklich tuen da es ein größers porjekt wird wolte es ich von anfang an gleich richtig planen. Darum frage ich auch hier.

Zitat:
Für Draw wäre dann noch interessant wohin du zeichnen lassen möchtest.
dafür ist ja fx und fy veranwortlich oder was meinst du mit dieser frage ?
ich möchte auch nur das obj neu zeichen lassen was sich gerade ändert.

Zitat:
Ich weiß nicht ob du in deinem Tut auch schon was über Interfaces und abstrakte
habe ich. Aber ich weiß im moment nicht was ein Interfaces hier zu tuen hätte ich stelle mir ein interfaces immer so vor:
du möchte eine grafik engine schreiben und möchtes verschiende grafik system verwenden z.b. openGL, DX, Canvas, etc. aber bei meiner GUI wüste ich jetzt nicht wo es da verwendung finden sollte.

eine frage habe ich aber noch:
verwaltung der obj.
ich möchte gerne das jedes obj z.b. ein panel sein obj. selsbt verwalten kann dies soll über ein schalter gemacht werden. d.h. wenn diese schalter auf True ist soll die eigene liste verwendet werden und wenn dierser auf False ist(standart einstellung) soll es in die allgemeine liste eingefügt werden.
Problem ist hier die umsetzung. Ein kleines beispiel währe nicht schlecht. Ich wollte wohl TObjectList nehmen..

Da dies mein erstes richtiges OOP programm ist wollte ich es gleich richtig planen damit ich nicht alles von vorne schreiben muss weil ich festelle das irgenwas nicht funktioniert.
Das währe ja ärgerlich.
Michael Springwald
MFG
Michael Springwald,
Bitte nur Deutsche Links angeben Danke (benutzte überwiegend Lazarus)
  Mit Zitat antworten Zitat
mimi

Registriert seit: 1. Dez 2002
Ort: Oldenburg(Oldenburg)
2.008 Beiträge
 
FreePascal / Lazarus
 
#7

Re: OOP Problem: änderungen werden nicht übernommen

  Alt 25. Dez 2005, 14:57
das ist die "neue klasse" habe ein paar änderung gemacht die ich übersehen hatte
Delphi-Quellcode:
TStdObj = class
  private
    FName:String; // Enhält den Namen des Obj
    FCaption:String; // Enhält das was Angezeigt wird
    FTag:Integer; // unBelengt
    Fx:Integer; // die X Position vom OBJ
    Fy:Integer; // die Y Position vom ObJ
    fw:Integer; // Die Breite vom Obj
    Fh:Integer; // die Höhe vom Obj
    procedure SetCaption(Caption:String);
    procedure SetNamen(Namen:String);
  public
    constructor Create(obj:TStdObj);
    destructor Free;
    procedure Draw;
  published
    property Name:string read fName write SetNamen;
    property Caption:string read fCaption write SetCaption;
  end;
ps: warum wird Name als schlüsswort hier angezeigt und nicht als normale variable ?
Michael Springwald
MFG
Michael Springwald,
Bitte nur Deutsche Links angeben Danke (benutzte überwiegend Lazarus)
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#8

Re: OOP Problem: änderungen werden nicht übernommen

  Alt 25. Dez 2005, 18:26
Zitat von mimi:
was meisnt du mit "setter" ?
Wenn du Properties verwendest, dann ja eigentlich nur aus der Idee heraus, nicht direkt auf einen Wert zu zugreifen. Dafür gibt es gleich mehrere Gründe, einerseits interessierst du dich in der OOP nie für die konkrete Art wie ein Wert abgespeichert wird. Ob es in einer Liste, einem Array, einer Hashtable, einem Baum, einer Halde,.... ist ändert für dich (von aussen kommend) nichts. Das andere ist natürlich, dass du gerne Invarianten überprüfen möchtest (Vor- und Nachbedingungen).
Deswegen sind Variablen in der OOP eigentlich immer privat und du greifst eigentlich nie direkt auf sie zu (es lässt sich immer vermeiden). Statt dessen benutzt du eine Methode, die einen Wert setzt (Setter) und eine Methode die dir einen Wert liefert (Getter).
Natürlich wird dir der Setter häufiger begegnen (hier prüfst du beim setzen ob der Wert gültig ist). Aber auch getter machen Sinn, wenn du zum Beispiel eine Liste von Zahlen hast und die größte Zahl bekommen möchtest, könntest du entweder immer die größte Zahl in einer Variablen speichern oder du sortierst die aufsteigend und nimmst das letzte Element oder du durchläufst die gesamte Liste und suchst das Größte. Wie du siehst leisten alle Methoden genau das gleiche, doch warum sollte es dich von aussen kommend interessieren? Du willst nur das größte Element. Hast du jetzt eine Methode getGreatestOne, liefert die dir irgendwie das Größte Element (alles was du willst).
In Delphi verbergen Properties nur den expliziten Aufruf solcher Methoden (du kannst natürlich auch direkt die Variable schreiben oder lesen).

Zitat von mimi:
Zitat:
Für Draw wäre dann noch interessant wohin du zeichnen lassen möchtest.
dafür ist ja fx und fy veranwortlich oder was meinst du mit dieser frage ?
ich möchte auch nur das obj neu zeichen lassen was sich gerade ändert.
Ich meine du möchtest so etwas wie einen Button zeichnen, dann musst du doch angeben wohin gezeichnet werden soll. Wenn du dir in Delphi die "Draws" anschaust, wirst du häufig sehen, dass man ein Canvas übergibt auf das gezeichnet werden kann. Das wäre eventuell auch bei dir nötig. Aber ich glaube du möchtest jetzt erstmal nur fertige Buttons (u.Ä.) platzieren, oder?

Zitat von mimi:
habe ich. Aber ich weiß im moment nicht was ein Interfaces hier zu tuen hätte ich stelle mir ein interfaces immer so vor:
du möchte eine grafik engine schreiben und möchtes verschiende grafik system verwenden z.b. openGL, DX, Canvas, etc. aber bei meiner GUI wüste ich jetzt nicht wo es da verwendung finden sollte.
Nun ja, Interfaces sind echt wichtig zu verstehen. Sie bieten einem wie gesagt eine Menge Möglichkeiten.
Ein Interface ist erstmal nur eine Sammlung an Methoden. Du weißt nur durch die Dokumentation was die einzelnen Methoden machen sollen und du weißt was für Argumente sie bekommen. Das wars. Ein Interface implementiert aber keine dieser Methoden.
Jede Klasse kann von genau einer Klasse erben, sie kann aber zusätzlich noch beliebig viele Interfaces implementieren. Ein Interface zu implementieren heißt dabei, dass jede abstrakte Methode des Interfaces in der Klasse implementiert werden muss.
Implementiert also eine Klasse ein Interface, so wird dir zugesichert, dass diese Klasse alle Methoden des Interface besitzt.

Das eigentlich Wichtige an diesen Dingern ist eben diese Zusicherung. Wenn du dein Programm erweiterst, möchtest du nicht für jede Erweiterung das Rad neu erfinden (nicht in der OOP). Also versuchst du den gemeinsamen Nenner zu finden und zu verwenden. Wichtig ist, dass jede Klasse immer die Eigenschaften ihrer Vorfahren und der implementierten Interfaces hat. Ein Interface entspricht weitgehend einer abstrakten Klasse, allerdings besitzt ein Interface ausschließlich abstrakte Methoden (eine abstrakte Klasse besitzt nur mindestens eine abstrakte Methode).

Das ganze mal etwas deutlicher an einem Beispiel:

Delphi-Quellcode:
type
  TDrawable = Interface
    procedure setPosX(const Position : Integer);
    procedure setPosY(const Position : Integer);
    procedure Draw(const Canvas : TCanvas);
  end;

  TDrawableButton = class(TInterfacedObject, TDrawable)
    protected
      procedure OnClick;
    public
      procedure setPosX(const Position : Integer);
      procedure setPosY(const Position : Integer);
      procedure Draw(const Canvas : TCanvas);
  end;

  TDrawablePanel = class(TInterfacedObject, TDrawable)
    private
      FPosX, FPosY : Integer;
      FColor : TColor;
    protected
      procedure setColor(const Color : TColor);
    public
      procedure setPosX(const Position : Integer);
      procedure setPosY(const Position : Integer);
      procedure Draw(const Canvas : TCanvas);
      property Color : TColor read FColor write setColor;
  end;
....
  procedure doFoo;
  var Drawable : TDrawable;
  begin
    DrawAble := TDrawablePanel.Create;
    // Achtung, DrawAble hat nur die Eigenschaften des Inteface!
    // also nur die Methoden setPosX/Y und Draw
    DrawAble.Draw(Form1.Canvas);
    ...
  end;
Ok, kein großartiges Beispiel, aber soll ja auch nur kurz etwas zeigen. Hier siehst du erstmal dass du zwei verschieden Objekte mit unterschiedlichen Eigenschaften hast. Ein TDrawableButton hat eine Methode OnClick, aber eben keine Farbe, diese hat dann aber ein TDrawablePanel. Trotzdem sind beide vom Typ TDrawable, besitzen also beide eine Methode draw zum Zeichnen und bei beiden kann man die X und Y Position setzen. In diesem Beispiel wird der Sinn vielleicht noch nicht all zu klar, aber vielleicht siehst du schon, dass du nun ein beliebiges TDrawable auf immer den selben Canvas zeichnen könntest. Dazu übergibst du nur noch ein TDrawable, du weißt ja dass es ein Draw hat. Diesem Draw übergibst du den Canvas auf den gezeichnet werden kann und dich interessiert es nicht ob es sich um ein TDrawableButton, TDrawablePanel oder gar ein TDrawableHastDuNichtGesehen handelt.

Genauso leicht kannst du so ein TNotifyable definieren, dass eine Nachricht annimmt. Wenn du nun ein Hauptinstanz hast, die eine Liste von TNotifyalbes verwaltet, dann müsstest du bei einem Ereignis nur jedem dieser Objekte die Nachricht übergeben...

Hoffe du siehst was ich meine, ist wirklich wichtig in der OOP. Kommen neue Klassen hinzu, ist dir das egal. Implementieren sie ein Interface, stellen sie mindestens diese Funktionen zur Verfügung und mehr interessiert dich dann garnicht.

Zitat von mimi:
eine frage habe ich aber noch:
verwaltung der obj.
ich möchte gerne das jedes obj z.b. ein panel sein obj. selsbt verwalten kann dies soll über ein schalter gemacht werden. d.h. wenn diese schalter auf True ist soll die eigene liste verwendet werden und wenn dierser auf False ist(standart einstellung) soll es in die allgemeine liste eingefügt werden.
Problem ist hier die umsetzung. Ein kleines beispiel währe nicht schlecht. Ich wollte wohl TObjectList nehmen..
Ich verstehe dein Frage ehrlich gesagt nicht ganz. Was heißt denn "sein obj. selbst verwalten?". Genauer gesagt was soll denn verwaltet werden? Wenn du hier so etwas wie Kinder haben meinst, da würde ich dir auch zu einer TObjectList raten. Auch zu Interfaces, wenn du hier ein Interface hast, dass ein Add und ein Remove (oder Ähnliches) bietet, dann könntest du damit leicht in jeder Klasse die dieses Interface implementiert ein Objekt hinzufügen oder entfernen.

Gruß Der Unwissende
  Mit Zitat antworten Zitat
mimi

Registriert seit: 1. Dez 2002
Ort: Oldenburg(Oldenburg)
2.008 Beiträge
 
FreePascal / Lazarus
 
#9

Re: OOP Problem: änderungen werden nicht übernommen

  Alt 25. Dez 2005, 19:05
Zitat:
Ich verstehe dein Frage ehrlich gesagt nicht ganz. Was heißt denn "sein obj. selbst verwalten?". Genauer gesagt was soll denn verwaltet werden? Wenn du hier so etwas wie Kinder haben meinst, da würde ich dir auch zu einer TObjectList raten. Auch zu Interfaces, wenn du hier ein Interface hast, dass ein Add und ein Remove (oder Ähnliches) bietet, dann könntest du damit leicht in jeder Klasse die dieses Interface implementiert ein Objekt hinzufügen oder entfernen.
Nun ja z.b. ich habe jetzt 20 Komponenten erstellt(egal was) wird ja 20 mal die Create funtkion des standart obj aufgerufen. Diese obj. werden dann einmal gezeichnet was ist aber wenn ein bestimmte Komponenten neugezeichnet werden soll/muss wie greife ich auf diese komponenten zu ?
z.b.:
2 Diese Komponenten müssen neugezeichnet werden a: wie finde ich herraus welche das sind ?
b: wie kann ich auf diese zugreifen ?

hätte ich eine liste mit komponenten könnte ich ja einfach schauen wo sollgeändert werden auf True steht, weißt du was ich damit meine ?

und mit selber verwalten dachte/meine ich folgendes:
Unter Delphi gibt es ja eine "Lange" liste in mit komponenten die ich auf dem Formular habe, richtig ? d.h. alle komponenten die auf dem panel sind sind auch in der "allgemeine" liste. geau das wollte ich ändern. alle komponenten die komponenten aufnehmen soll sollen auch über eine eigene liste verfügen.

Natürlich währe das durchsuchen wird schwrig, z.b. wenn ich eine bestimmte komponente suchen muss dann muss ich ja ersteinaml die 1. liste durchsuchen und dann die weitern aber welche ?
da fällt mir im moment nur eine lösung ein:
in der 1. liste steht ein verweis auf die andern listen.
das kann ich ja beim installsiern feststellen.
Weißt du wie ich es mir vorstelle ?

oder mal andres(genau das gleiche problem nur anderes beschrieben):
Ich habe die 20 Komponenten und möchte auf die 2 zugreifen z.b. über FindKomponente(2) oder FindKomponente('Zweitekomponente');

Vielen dank für deine Tipps. Nur das mit den interface verstehe ich immer noch nicht so ganz. scheint aber ein mächtige funktion zu sein in der OOP. Das mit der Draw funktion wollte ich auch indrect nutzen.

weil ich nutze für die Grafik dastellung nicht canvas sonder direkt die GDI habe da eine unit gefunden:http://www.benibela.de
ich habe jedoch ein kleine extra unit geschrieben die die verwendung vereinfacht *G*

mit Setter und Getter meinst du sowas:
Setter=procedureen die was Setzten
Getter=funktionen
Michael Springwald
MFG
Michael Springwald,
Bitte nur Deutsche Links angeben Danke (benutzte überwiegend Lazarus)
  Mit Zitat antworten Zitat
Alt 25. Dez 2005, 19:21     Erstellt von Amateurprofi
Dieser Beitrag wurde von r_kerber gelöscht. - Grund: Ist völlig OT!
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#10

Re: OOP Problem: änderungen werden nicht übernommen

  Alt 25. Dez 2005, 20:36
Ok,
hier wären wir schon fast wieder bei den Interfaces. Ist eigentlich gar nicht so schwer, du musst dir nur etwas mehr überlegen welche Klassen was gemeinsam haben.
Ich hoffe ich bin hier nicht zu sprunghaft oder unverständlich oder so, beschwer dich einfach immer wenn das der Fall ist und frag nach! Ist wichtig und richtig!

Da ich nicht weiß wie gut dein Tutorial zu OOP war (und ehrlich gesagt hab ich echt einige gebraucht um den Sinn zu verstehen), möchte ich nochmal ein wenig auf die Ideen eingehen.
Die OOP ist eigentlich nur ein einfacher Versuch, das reale Leben auf die Programmierung abzubilden. Unnötig zu sagen, dass es nicht trivial ist.
Bei der Beobachtung des "realen Leben" viel auf, dass wir alles in Klasen aufteilen können. Diese Unterteilungen kann man dann auch noch verfeinern (also sowas wie Tier -> Säugetier -> Affe -> Schimpanse -> Chita (wie auch immer man die schreibt)).
Man weiß also sehr viel über einen sehr speziellen Schimpansen, aber vor allem auch, dass Chita ein Schimpanse ist. Du weißt also das Chita Fell hat, ein Menschenaffe ist, Bananen ist, ...
Das kannst du nicht über alle Säugetiere sagen, aber alles was du über ein Säugetier sagen kannst gilt halt auch für Chita. Wichtig ist es also, dass du immer alle Eigenschaften in einer Verfeinerung bei behälst.

Die andere wichtige Sache dieser Unterteilung ist, dass ich auch andere Säugetiere haben kann (Tier -> Säugetier -> Bär -> Balu -> ...). Hab ich ein Säugetier, weiß ich dass es Sauerstoff zum atmen braucht, das gilt sicherlich für Chita und Balu, aber eben auch für jedes andere Säugetier. Aber gilt dass auch für jedes Tier? (Tier -> Fisch -> Nemo) Wohl eher nicht.

Also fasse ich alles nach bestimmten Eigenschaften zusammen und kann dabei beliebig verfeinern. In der OOP unterscheidet man nicht die Stufe der Verfeinerung, alles ist einfach ein Klasse (nichts Familie, Art, Gattung, ...). Alles was existiert ist dann eine Instanz. Etwas anschaulicher kannst du sagen, Klassen sind der Bauplan, Instanzen/Objekte sind das Gebaute.
Also sind Tier, Fisch, Säugetier, Affe, ... alles nur Klassen die gewisse Eigenschaften festlegen. Chita, Nemo und Balu sind hingegen Instanzen, sie wurden nach dem jeweiligen Bauplan angefertigt. Natürlich kann man beliebig viele Instanzen einer Klasse anlegen (z.B. könnte auch Charlie ein Schimpanse sein).

Das ist der eine Teil der OOP. Du erstellst einfach immer einen Bauplan, der genau die Eigenschaften von etwas festlegt. Aber mehr hast du nicht, nur den Bauplan. Beim Programmstart erstellst du dann aus den einzelnen Bauplänen konkrete Instanzen. Dein Programm ist dabei ihre Welt. Eine Instanz führt immer ein begrenztes Leben. Sie kann erst nach der Welt (dem Programmstart) entstehen und endet auch mit der Welt (Programmende). Länger kann nichts leben, aber früher sterben geht immer (Destruktor aufruf).
Jede Instanz führt dabei auch ein ganz eigenes Leben und kann seine Eigenschaften individuell ändern. Aber jede Instanz hat halt auch nur genau die Eigenschaften, die in der Klasse stehen.
Da jede Instanz ihr eigenes Leben hat, interessieren sich Instanz erstmal nicht weiter führ einander, sie leben halt irgendwo auf der Welt. Was genau in ihnen vorgeht weiß man nicht, interessiert einen aber auch nicht.
Wenn man eine Instanz findet, gibt es die Möglichkeit mit dieser zu kommunizieren. Dabei ist aber (durch die Klasse) festgelegt, wie diese Kommunikation aussieht. Alles was öffentlich ist (public oder published) kann jeder zur Kommunikation benutzen. Dinge die privat sind, kann nur die Instanz selbst sehen, Dinge die geschützt sind (protected), sehen nur Nachfahren oder Instanzen der gleichen Klasse.
Die Kommunikation entspricht also dem Aufruf von Methoden (proceduren / funktionen).

Das war's eigentlich schon so ziemlich.


Hoffe es war soweit verständlich. Ist wie gesagt nur grob die Grundidee. Daraus hervor gehen tun die typischen Punkte, was OOP möchte (die findest du mit google).

Was du jetzt machen möchtest lässt sich geradezu ideal in OOP modellieren. Du hast ein Hauptformular (dein GUI). Hier möchtest du Elemente platzieren. Diese Elemente sind sichtbar. Einige von ihnen (und das Hauptformular) können andere Elemente aufnehmen.

Das sind alles Eigenschaften. Du musst jetzt nur noch die Eigenschaften geschickt zusammen fassen. Es sollte immer alles was zusammen gefasst werden kann auch zusammen gefasst werden (natürlich kann man alles übertreiben, meine implizit natürlich sinnvoll).
Du hast hier also einmal eine Klasse von Objekten, die Elemente aufnehmen können.
Dann hast du eine Klasse von Elementen die gezeichnet werden können.
Eventuell hast du ja auch noch eine Klasse von Elementen, die nicht gezeichnet werden können.

Nehmen wir nur die ersten beiden Eigenschaften.
Du hast also dein Hauptformular, dass kann Objekte aufnehmen.
Die Objekte, die du darauf ablegst können alle gezeichnet werden, aber nur einige davon können Objekte aufnehmen.

Mit zwei Klassen ist es etwas schwer Interfaces zu rechtfertigen, aber ich möchte hier noch nichts als Beispiel konstruieren, verwirrt wohl eher. Die Idee eines Interfaces noch einmal:
Du könntest jetzt einfach Eigenschaften in ein Interface packen. Du tust dort einfach alles rein, was es an Gemeinsamkeiten gibt. Objekte aufnehmen bringt nur etwas, wenn diese Objekte auch wieder entfernt werden können. Und wenn du suchen möchtest, musst du natürlich alle Objekte bekommen können.
Das alles ist doch super und daraus bauen wir einfach mal ein Interface (einen Bauplan, aus dem aber nichts direkt gebaut werden kann).

Delphi-Quellcode:
type
  IKannObjekteAufnehmen = Interface
    procedure fuegeObjektHinzu(const neuesObjekt : TObject);
    procedure entferneObjekt(const Objekt : TObject);
    function getListeDerObjekte : TObjectList; // entschuldige das get, aber ist ja fast Konvention
  end;
Ok, dies wäre einfach nur eine Beschreibung von Eigenschaften. Alles was IKannObjekteAufnehmen (führendes I weil Interface) implementiert hat diese drei Methoden. Was genau ein Objekt macht, wenn ich fuegeObjektHinzu aufrufe ist mir hier vollkommen egal.
Am Beispiel der Säugetiere, jedes Säugetier hat eine Lunge um zu atmen, aber jedes Säugetier atmet unterschiedlich. Was in der Lunge passiert und wie groß das Lungenvolumen ist und und und ist mir egal.

Hättest du hier eine Klasse, müsstest du für die Klasse die Implementierung angeben. Das hier kannst du in eine eigene Datei in den Interface-Teil schreiben und die Datei wäre fertig.

Die andere Eigenschaft ist natürlich das man etwas zeichnen kann. Dazu benötigt man nur eine Funktion, die für das zeichnen zuständig ist. Also
Delphi-Quellcode:
type
  IKannGezeichnetWerden = Interface
    procedure draw;
  end;
Ok, jetzt siehst du gleich (ausnamhsweise beabsichtigt) einen klassischen Designfehler. Es würde so funktionieren, wie es hier steht, aber IKannObjekteAufnehmen kann halt jedes Objekt aufnehmen, ohne Einschränkung. Du möchtest aber doch eigentlich nur deine (zeichenbaren) Objekte aufnehmen. Hm, wenn wir also erst festgelegt hätten, was zeichenbar ist...

Also erst letzte Deklaration von IKannGezeichnetWerden erstellen und dann :

Delphi-Quellcode:
type
  IKannObjekteAufnehmen = Interface
    procedure fuegeObjektHinzu(const neuesObjekt : IKannGezeichnetWerden);
    procedure entferneObjekt(const Objekt : IKannGezeichnetWerden);
    function getListeDerObjekte : TObjectList; // entschuldige das get, aber ist ja fast Konvention
  end;
Jetzt übergibst du nur noch IKannGezeicnetWerden-Objekte. Das heißt alles was du übergibst hat immer die Methode draw (du weißt nicht was sonst noch, aber die hat es).
Ja, jetzt siehst du vielleicht schon, warum ich vorhin über dein Hauptformular / die GUI nicht gesagt habe, dass sie zeichenbar ist. Das mag zwar sein, aber die möchtest du sicherlich nicht sich selbst hinzufügen können (und erst recht nicht einem Panel oder ähnlichem).

Deine Verwaltung kannst du nun auf diese Art und Weise vornehmen. Du legst dir erst Interfaces mit den zusammengehörigen Eigenschaften an und implementierst diese dann. Wenn etwas ein Interface implementiert, kann es auch dort übergeben werden, wo ein solches Interface verlangt wird (wenn ich einen Affen will, ist Chita ok, auch wenn ich ein Säugetier will. Möchte ich aber einen Hund, tut es Chita nicht, kein bellen, ...).

Ich glaube das reicht erstmal. Hoffe habe hier nicht zuviel auf einmal gepostet, frag gerne nach!

Gruß Der Unwissende
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:29 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz