Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Setter mehrfach überschreiben. (https://www.delphipraxis.net/185422-setter-mehrfach-ueberschreiben.html)

Bjoerk 8. Jun 2015 16:52


Setter mehrfach überschreiben.
 
Ich habe 3 Klassen:
Delphi-Quellcode:
  TDingensBase = class
  protected
    function GetTest: string; virtual; abstract;
    procedure SetTest(const Value: string); virtual; abstract;
    property Test: string read GetTest write SetTest;
  end;

  TDingens = class(TDingensBase)
  protected
    FTest: string;
    function GetTest: string; override;
    procedure SetTest(const Value: string); override;
  public
    property Test;
  end;

  TDingensEx = class(TDingens)
  private
    procedure SetTest(const Value: string); override;
  end;
Das seh ich doch richtig, daß man die property Test nicht 2 mal veröffenlichen muß und das für Test von TDingensEx der Setter davon benutzt wird? :oops:

stahli 8. Jun 2015 17:37

AW: Setter mehrfach überschreiben.
 
Korrekt.

Bjoerk 8. Jun 2015 18:28

AW: Setter mehrfach überschreiben.
 
Ok, thanx Stahli. BTW, gibt’s da einen Trick um zu überprüfen, ob man eine Methode vergessen hat zu überschreiben. Wenn man die Methode ohne override einfügt gibt der Compiler ja schön die Warnung (verdeckt Methode der Basisklasse). Aber wenn man die Methode ganz vergessen hat, meckert "er" nicht, man würde im dem Fall ja ggf. die abstrakten verwenden? Ist mir noch nicht passiert. Verschwindet der Wert dann im Nirwana oder krachst dann?

himitsu 8. Jun 2015 18:33

AW: Setter mehrfach überschreiben.
 
Property mit Name, aber ohne Typ-Definition:

Man kann auf diese Weise das Property in der Sichbarkeit verschieben (aber immer nur nach oben -> sichtbarer) oder es erweitern/ändern (z.B. das Default oder auch Getter/Setter ändern/hinzufügen).

Siehe TCustomEdit und TEdit.
TCustomEdit implementiert die Grundfunktionen und TEdit setzt nur noch die Sichtbarkeiten. So kann man von TCustomEdit ableiten und muß nicht die Sichtbarkeiten von TEdit übernehmen.


Abstract + Override vergessen = Compilerwarnung, beim erstellen einer Instanz.
siehe z.B.
Delphi-Quellcode:
SL := TStrings.Create;

stahli 8. Jun 2015 18:33

AW: Setter mehrfach überschreiben.
 
Wenn Du eine abstrakte Methode aufrufst, bekommst Du eine Fehlermeldung.
Abstrakte Methoden sind also nicht schädlich, aber Du darfst sie halt nicht aufrufen ohne sie zu überschreiben.

Bjoerk 9. Jun 2015 13:13

AW: Setter mehrfach überschreiben.
 
Jetzt bekomm ich ca. 1600 Warnungen wie diese. Ist das normal. Wohl kaum?? :shock:

[DCC Warnung] uGraphicObjectList.pas(1353): W1020 Instanz von 'TWerkzeug3' mit der abstrakten Methode 'TWerkzeug.GetDimensionAlignRight' wird angelegt
[DCC Warnung] uGraphicObjectList.pas(1353): W1020 Instanz von 'TWerkzeug3' mit der abstrakten Methode 'TWerkzeug.GetPosAlign' wird angelegt
[DCC Warnung] uGraphicObjectList.pas(1353): W1020 Instanz von 'TWerkzeug3' mit der abstrakten Methode 'TWerkzeug.GetPositionAlign' wird angelegt
[DCC Warnung] uGraphicObjectList.pas(1353): W1020 Instanz von 'TWerkzeug3' mit der abstrakten Methode 'TWerkzeug.GetTextAlign' wird angelegt
[DCC Warnung] uGraphicObjectList.pas(1353): W1020 Instanz von 'TWerkzeug3' mit der abstrakten Methode 'TWerkzeug.GetOddHatchPenStyle' wird angelegt
[DCC Warnung] uGraphicObjectList.pas(1353): W1020 Instanz von 'TWerkzeug3' mit der abstrakten Methode 'TWerkzeug.GetEvenHatchPenStyle' wird angelegt
[DCC Warnung] uGraphicObjectList.pas(1353): W1020 Instanz von 'TWerkzeug3' mit der abstrakten Methode 'TWerkzeug.GetSectionTriangleWidth' wird angelegt
[DCC Warnung] uGraphicObjectList.pas(1353): W1020 Instanz von 'TWerkzeug3' mit der abstrakten Methode 'TWerkzeug.GetSectionAlign' wird angelegt
[DCC Warnung] uGraphicObjectList.pas(1353): W1020 Instanz von 'TWerkzeug3' mit der abstrakten Methode 'TWerkzeug.GetSectionFilledTriangle' wird angelegt

himitsu 9. Jun 2015 14:10

AW: Setter mehrfach überschreiben.
 
Siehe Antwort #4, die letzten beiden Zeilen.

stahli 9. Jun 2015 14:19

AW: Setter mehrfach überschreiben.
 
Dann lag ich wohl falsch... :oops:
Ich dachte, man darf die Methode dann nur nicht aufrufen...

Bjoerk 9. Jun 2015 14:29

AW: Setter mehrfach überschreiben.
 
Ein Override hab ich nicht vergessen. Es ist nur so, daß die einzelnen Klassen, die davon abgeleitet sind, nicht jede Methode bzw. jede Property haben.
Delphi-Quellcode:
unit uWerkzeug;

interface

uses
  SysUtils, Classes, Graphics, Dialogs, Math, VirtualTrees, uIniDataFile,
  uUtils, uRecords, uClasses, uPolygon, uPolygonEx, uPropUtils, uPropArrays, uBewehrung;

// Es gibt
// TWerkzeug, TWerkzeug0, TWerkzeug1, TWerkzeug2, TWerkzeug3:

// TWerkzeug = diese unit;

// TWerkzeug0 = class(TWerkzeug);

// TWerkzeug1 = class(TWerkzeug0);
// TWerkzeug2 = class(TWerkzeug0);
// TWerkzeug3 = class(TWerkzeug0);

// *** Die Nummern hinter den Getters/Setters von TWerkzeug zeigen die Klassen an,
// in denen diese Getter/Setter überschrieben werden.

// *** Die Nummern hinter den Properties von TWerkzeug zeigen die Klassen an,
// in denen diese Props veröffentlich werden.

type
  TWerkzeug = class
  protected
    function GetNode: PVirtualNode; virtual; abstract; // 0;
    function GetTyp: TGraphicTyp; virtual; abstract; // 0;
    function GetEnabled: boolean; virtual; abstract; // 0;
    function GetComment: string; virtual; abstract; // 0;
    function GetCircleRadius: double; virtual; abstract; // 1; // 2; // 3;
    function GetScalemX1: double; virtual; abstract; // 0;
    function GetScalemX2: double; virtual; abstract; // 0;
    function GetScalemY1: double; virtual; abstract; // 0;
    function GetScalemY2: double; virtual; abstract; // 0;
    function GetScalecmSimpleMargin: double; virtual; abstract; // 0;
    function GetScalecmMarginTop: double; virtual; abstract; // 0;
    function GetScalecmMarginBottom: double; virtual; abstract; // 0;
    function GetScalecmMarginLeft: double; virtual; abstract; // 0;
    function GetScalecmMarginRight: double; virtual; abstract; // 0;
    function GetScalemWidth: double; virtual; abstract; // 1; // 2; // 3;
    function GetScalemHeight: double; virtual; abstract; // 1; // 2; // 3;
    function GetScalemWidthX: double; virtual; abstract; // 1;
    function GetScalemHeightY: double; virtual; abstract; // 1;
    function GetScalemLength: double; virtual; abstract; // 1; // 3;
    function GetScalemRadius: double; virtual; abstract; // 1; // 2; // 3;
    function GetLineAngle: double; virtual; abstract; // 1; // 3;
    function GetDesigning: boolean; virtual; abstract; // 0;
    function GetP1: TCadFLoatPoint; virtual; abstract; // 0;
    function GetP2: TCadFLoatPoint; virtual; abstract; // 0;
    function GetFontMode: boolean; virtual; abstract; // 1;
    function GetSelected: boolean; virtual; abstract; // 0;
    function GetSmoothing: boolean; virtual; abstract; // 2;
    function GetAsCirclePie: boolean; virtual; abstract; // 2;
    function GetShowPolygonLines: boolean; virtual; abstract; // 2;
    function GetClosedPolygon: boolean; virtual; abstract; // 2;
    function GetCrossRect: boolean; virtual; abstract; // 2;
    function GetCircleAlpha: double; virtual; abstract; // 0;
    function GetPositionAlpha: double; virtual; abstract; // 1;
    function GetCircleBeta: double; virtual; abstract; // 0;
    function GetArrowA: double; virtual; abstract; // 1;
    function GetArrowB: double; virtual; abstract; // 1;
    function GetDimensionA: double; virtual; abstract; // 1;
    function GetDimensionB: double; virtual; abstract; // 1;
    function GetDimensionVersatz: double; virtual; abstract; // 1;
    function GetPosDiameter: double; virtual; abstract; // 1;
    function GetPosQuadratSize: double; virtual; abstract; // 3;
    function GetScaleCMDistribution: double; virtual; abstract; // 1; // 3;
    function GetOffsetX: double; virtual; abstract; // 1;
    function GetOffsetY: double; virtual; abstract; // 1;
    function GetArrowAlpha: double; virtual; abstract; // 1;
    function GetHatchFrequency: double; virtual; abstract; // 2;
    function GetTextAlpha: double; virtual; abstract; // 1;
    function GetAngle: double; virtual; abstract; // 0;
    function GetArrowAlign: TArrowAlign; virtual; abstract; // 1;
    function GetText: string; virtual; abstract; // 1; // 3;
    function GetCaption: string; virtual; abstract; // 1;
    function GetOwnerText: string; virtual; abstract; // 1;
    function GetSeite: string; virtual; abstract; // 1;
    function GetPenMMWidth: double; virtual; abstract; // 0;
    function GetDimension: TDimensionType; virtual; abstract; // 1;
    function GetDimensionStyle: TDimensionStyle; virtual; abstract; // 1;
    function GetDimensionOrientation: TDimensionOrientation; virtual; abstract; // 1;
    function GetDimensionAlignLeft: TDimensionAlign; virtual; abstract; // 1;
    function GetDimensionAlignRight: TDimensionAlign; virtual; abstract; // 1;
    function GetPosAlign: TPosAlign; virtual; abstract; // 1;
    function GetPositionAlign: TPositionAlign; virtual; abstract; // 1;
    function GetTextAlign: TTextAlign; virtual; abstract; // 1;
    function GetOddHatchPenStyle: TPenStyle; virtual; abstract; // 2;
    function GetEvenHatchPenStyle: TPenStyle; virtual; abstract; // 2;
    function GetSchnittTriangleWidth: double; virtual; abstract; // 1;
    function GetSchnittAlign: TSchnittAlign; virtual; abstract; // 1;
    function GetSchnittFilledTriangle: boolean; virtual; abstract; // 1;
    function GetTextA: string; virtual; abstract; // 1;
    function GetTextB: string; virtual; abstract; // 1;
    function GetHintStyle: TCornerStyle; virtual; abstract; // 1;
    function GetKoteTriangleWidth: double; virtual; abstract; // 1;
    function GetKoteAlign: TSchnittAlign; virtual; abstract; // 1;
    function GetAspectRatio: boolean; virtual; abstract; // 1;
    function GetExtraListEnabled: boolean; virtual; abstract; // 1; // 3;
    function GetTopReinforcement: boolean; virtual; abstract; // 3;
    function GetKoteFilledTriangle: boolean; virtual; abstract; // 1;
    function GetNEckCount: integer; virtual; abstract; // 2;
    function GetHelpPolygonDistribution: integer; virtual; abstract; // 2;
    function GetStabPunktFilled: boolean; virtual; abstract; // 3;
    function GetNEckScalemA: double; virtual; abstract; // 2;
    function GetScalemmFlange: double; virtual; abstract; // 2;
    function GetScalemmThickness: double; virtual; abstract; // 2;
    function GetPropertySelected: boolean; virtual; abstract; // 0;
    function GetPen: TPen; virtual; abstract; // 0;
    function GetFont: TFont; virtual; abstract; // 0;
    function GetBrushColor: TColor; virtual; abstract; // 1; // 2;
    function GetBrushStyle: TBrushStyle; virtual; abstract; // 2;
    function GetPolygon: TPolygon; virtual; abstract; // 2;
    function GetPolygonEx: TPolygonEx; virtual; abstract; // 3;
    function GetDoubleLine: TDoubleLine; virtual; abstract; // 1;
    function GetMetaFile: TMetaFile; virtual; abstract; // 1;
    function GetStl: TStlBewehrung; virtual; abstract; // 3;
    function GetMtl: TMtlBewehrung; virtual; abstract; // 3;
    function GetSnapPoints: TFloatPoints; virtual; abstract; // 0;
    function GetProfil: string; virtual; abstract; // 2;
    function GetScale: TScale; virtual; abstract; // 0;
    function GetBoundRect: TFloatRectEx; virtual; abstract; // 1; // 2; // 3;
    function GetHaveBoundRect: boolean; virtual; abstract; // 1; // 2; // 3;
    function GetProp(Index: TProp): boolean; virtual; abstract; // 0;
    function GetAction(Index: TAction): boolean; virtual; abstract; // 0;
    function GetSimpleMargin: double; virtual; abstract; // 0;
    function GetMargin: TMargin; virtual; abstract; // 0;
    procedure SetNode(const Value: PVirtualNode); virtual; abstract; // 0;
    procedure SetTyp(const Value: TGraphicTyp); virtual; abstract; // 0; // 1; // 2; // 3;
    procedure SetEnabled(const Value: boolean); virtual; abstract; // 0;
    procedure SetComment(const Value: string); virtual; abstract; // 0;
    procedure SetCircleRadius(const Value: double); virtual; abstract; // 1; // 2; // 3;
    procedure SetNewAngle(const Value: double); virtual; abstract; // 0;
    procedure SetScalemX1(const Value: double); virtual; abstract; // 0;
    procedure SetScalemX2(const Value: double); virtual; abstract; // 0;
    procedure SetScalemY1(const Value: double); virtual; abstract; // 0;
    procedure SetScalemY2(const Value: double); virtual; abstract; // 0;
    procedure SetScalecmSimpleMargin(const Value: double); virtual; abstract; // 0;
    procedure SetScalecmMarginTop(const Value: double); virtual; abstract; // 0;
    procedure SetScalecmMarginBottom(const Value: double); virtual; abstract; // 0;
    procedure SetScalecmMarginLeft(const Value: double); virtual; abstract; // 0;
    procedure SetScalecmMarginRight(const Value: double); virtual; abstract; // 0;
    procedure SetScalemWidth(const Value: double); virtual; abstract; // 1; // 2; // 3;
    procedure SetScalemHeight(const Value: double); virtual; abstract; // 1; // 2; // 3;
    procedure SetScalemWidthX(const Value: double); virtual; abstract; // 1;
    procedure SetScalemHeightY(const Value: double); virtual; abstract; // 1;
    procedure SetScalemLength(const Value: double); virtual; abstract; // 1; // 3;
    procedure SetScalemRadius(const Value: double); virtual; abstract; // 1; // 2; // 3;
    procedure SetLineAngle(const Value: double); virtual; abstract; // 1; // 3;
    procedure SetDesigning(const Value: boolean); virtual; abstract; // 0;
    procedure SetFontMode(const Value: boolean); virtual; abstract; // 1;
    procedure SetSmoothing(const Value: boolean); virtual; abstract; // 2;
    procedure SetAsCirclePie(const Value: boolean); virtual; abstract; // 2;
    procedure SetShowPolygonLines(const Value: boolean); virtual; abstract; // 2;
    procedure SetClosedPolygon(const Value: boolean); virtual; abstract; // 2;
    procedure SetCrossRect(const Value: boolean); virtual; abstract; // 2;
    procedure SetCircleAlpha(const Value: double); virtual; abstract; // 0;
    procedure SetPositionAlpha(const Value: double); virtual; abstract; // 1;
    procedure SetCircleBeta(const Value: double); virtual; abstract; // 0;
    procedure SetArrowA(const Value: double); virtual; abstract; // 1;
    procedure SetArrowB(const Value: double); virtual; abstract; // 1;
    procedure SetDimensionA(const Value: double); virtual; abstract; // 1;
    procedure SetDimensionB(const Value: double); virtual; abstract; // 1;
    procedure SetDimensionVersatz(const Value: double); virtual; abstract; // 1;
    procedure SetPosDiameter(const Value: double); virtual; abstract; // 1;
    procedure SetPosQuadratSize(const Value: double); virtual; abstract; // 3;
    procedure SetScaleCMDistribution(const Value: double); virtual; abstract; // 1; // 3;
    procedure SetOffsetX(const Value: double); virtual; abstract; // 1;
    procedure SetOffsetY(const Value: double); virtual; abstract; // 1;
    procedure SetArrowAlpha(const Value: double); virtual; abstract; // 1;
    procedure SetHatchFrequency(const Value: double); virtual; abstract; // 2;
    procedure SetTextAlpha(const Value: double); virtual; abstract; // 1;
    procedure SetAngle(const Value: double); virtual; abstract; // 0;
    procedure SetArrowAlign(const Value: TArrowAlign); virtual; abstract; // 1;
    procedure SetText(const Value: string); virtual; abstract; // 1; // 3;
    procedure SetCaption(const Value: string); virtual; abstract; // 1;
    procedure SetOwnerText(const Value: string); virtual; abstract; // 1;
    procedure SetSeite(const Value: string); virtual; abstract; // 1;
    procedure SetPenMMWidth(const Value: double); virtual; abstract; // 0;
    procedure SetDimension(const Value: TDimensionType); virtual; abstract; // 1;
    procedure SetDimensionStyle(const Value: TDimensionStyle); virtual; abstract; // 1;
    procedure SetDimensionOrientation(const Value: TDimensionOrientation); virtual; abstract; // 1;
    procedure SetDimensionAlignLeft(const Value: TDimensionAlign); virtual; abstract; // 1;
    procedure SetDimensionAlignRight(const Value: TDimensionAlign); virtual; abstract; // 1;
    procedure SetPosAlign(const Value: TPosAlign); virtual; abstract; // 1;
    procedure SetPositionAlign(const Value: TPositionAlign); virtual; abstract; // 1;
    procedure SetTextAlign(const Value: TTextAlign); virtual; abstract; // 1;
    procedure SetOddHatchPenStyle(const Value: TPenStyle); virtual; abstract; // 2;
    procedure SetEvenHatchPenStyle(const Value: TPenStyle); virtual; abstract; // 2;
    procedure SetSchnittTriangleWidth(const Value: double); virtual; abstract; // 1;
    procedure SetSchnittAlign(const Value: TSchnittAlign); virtual; abstract; // 1;
    procedure SetSchnittFilledTriangle(const Value: boolean); virtual; abstract; // 1;
    procedure SetTextA(const Value: string); virtual; abstract; // 1;
    procedure SetTextB(const Value: string); virtual; abstract; // 1;
    procedure SetHintStyle(const Value: TCornerStyle); virtual; abstract; // 1;
    procedure SetKoteTriangleWidth(const Value: double); virtual; abstract; // 1;
    procedure SetKoteAlign(const Value: TSchnittAlign); virtual; abstract; // 1;
    procedure SetAspectRatio(const Value: boolean); virtual; abstract; // 1;
    procedure SetExtraListEnabled(const Value: boolean); virtual; abstract; // 1; // 3;
    procedure SetTopReinforcement(const Value: boolean); virtual; abstract; // 3;
    procedure SetKoteFilledTriangle(const Value: boolean); virtual; abstract; // 1;
    procedure SetNEckCount(const Value: integer); virtual; abstract; // 2;
    procedure SetHelpPolygonDistribution(const Value: integer); virtual; abstract; // 2;
    procedure SetStabPunktFilled(const Value: boolean); virtual; abstract; // 3;
    procedure SetNEckScalemA(const Value: double); virtual; abstract; // 2;
    procedure SetScaleMMFlange(const Value: double); virtual; abstract; // 2;
    procedure SetScaleMMThickness(const Value: double); virtual; abstract; // 2;
    procedure SetPropertySelected(const Value: boolean); virtual; abstract; // 0;
    procedure SetBrushColor(const Value: TColor); virtual; abstract; // 1; // 2;
    procedure SetBrushStyle(const Value: TBrushStyle); virtual; abstract; // 2;
    procedure SetProfil(const Value: string); virtual; abstract; // 2;
    procedure SetScale(const Value: TScale); virtual; abstract; // 0; // 1; // 2; // 3;
  protected
    procedure MouseMove(const MovePt: TFloatPoint); virtual; abstract; // 0;
    procedure MouseMoveEx(const SelectRect: TFloatRectEx); virtual; abstract; // 0;
    function Center: TFloatPoint; virtual; abstract; // 0;
    function CircleCenter: TFloatPoint; virtual; abstract; // 1; // 2; // 3;
    function A: TFloatPoint; virtual; abstract; // 1;
    function B: TFloatPoint; virtual; abstract; // 1;
    function C: TFloatPoint; virtual; abstract; // 1;
    function LoadFromIniFile(Ini: TIniDataFileStream; const Section: string): boolean; virtual; abstract; // 0; // 1; // 2; // 3;
    function SaveToIniFile(Ini: TIniDataFileStream; const Section: string): boolean; virtual; abstract; // 0; // 1; // 2; // 3;
    procedure Assign(Value: TWerkzeug); virtual; abstract; // 0; // 1; // 2; // 3;
    function Compare(Value: TWerkzeug): boolean; virtual; abstract; // 0; // 1; // 2; // 3;
    procedure DrawObject(Canvas: TCanvas; const Plot: TPlotDevice); virtual; abstract; // 1; // 2; // 3;
    procedure DrawRegion(Canvas: TCanvas; const Plot: TPlotDevice); virtual; abstract; // 1; // 2; // 3;
    procedure SetRegion; virtual; abstract; // 1; // 2; // 3;
    procedure SetSnapPoints; virtual; abstract; // 1; // 2; // 3;
    procedure Rotate(const R: TFloatPoint; const Alpha: double); virtual; abstract; // 1; // 2; // 3;
    procedure ShiftXY(const ScalemValueX, ScalemValueY: double); virtual; abstract; // 1; // 2; // 3;
    procedure ShiftUV(const ScalemValueU, ScalemValueV: double); virtual; abstract; // 1; // 2; // 3;
    procedure FlipHorz(const Y: double); virtual; abstract; // 1; // 2; // 3;
    procedure FlipVert(const X: double); virtual; abstract; // 1; // 2; // 3;
    procedure Clear; virtual; abstract; // 0; // 1; // 2; // 3;
    procedure GraphicLoadFromFile(const FileName: string; const ppMM: double); virtual; abstract; // 1;
    procedure AssignGraphic(MF: TMetaFile; const ppMM: double; const Scale: TScale; SnapPoints: TFloatPoints); virtual; abstract; // 1;
    function ClipRectEx: TFloatRectEx; virtual; abstract; // 0;
    function ClipRect: TFloatRect; virtual; abstract; // 0;
    function Diagonal: double; virtual; abstract; // 0;
    function HaveMargin: boolean; virtual; abstract; // 0;
    procedure SetProps; virtual; abstract; // 1; // 2; // 3;
    procedure SetActions; virtual; abstract; // 1; // 2; // 3;
    function HaveTyp(const Value: TGraphicTyp): boolean; virtual; abstract; // 1; // 2; // 3;
    function CurrentTyp: boolean; virtual; abstract; // 1; // 2; // 3;
  protected
    property Node: PVirtualNode read GetNode write SetNode; // (0);
    property Typ: TGraphicTyp read GetTyp write SetTyp; // (0);
    property Enabled: boolean read GetEnabled write SetEnabled; // (0);
    property Comment: string read GetComment write SetComment; // (0);
    property Prop[Index: TProp]: boolean read GetProp; // (0);
    property Action[Index: TAction]: boolean read GetAction; // (0);
    property P1: TCadFLoatPoint read GetP1; // (0);
    property P2: TCadFLoatPoint read GetP2; // (0);
    property Pen: TPen read GetPen; // (0);
    property Font: TFont read GetFont; // (0);
    property Polygon: TPolygon read GetPolygon; // (2);
    property PolygonEx: TPolygonEx read GetPolygonEx; // (3);
    property DoubleLine: TDoubleLine read GetDoubleLine; // (1);
    property MetaFile: TMetaFile read GetMetaFile; // (1);
    property Stl: TStlBewehrung read GetStl; // (3);
    property Mtl: TMtlBewehrung read GetMtl; // (3);
    property SnapPoints: TFloatPoints read GetSnapPoints; // (0);
    property CircleRadius: double read GetCircleRadius write SetCircleRadius; // (1); // (2); // (3);
    property NewAngle: double write SetNewAngle; // (0);
    property ScalemX1: double read GetScalemX1 write SetScalemX1; // (0);
    property ScalemX2: double read GetScalemX2 write SetScalemX2; // (0);
    property ScalemY1: double read GetScalemY1 write SetScalemY1; // (0);
    property ScalemY2: double read GetScalemY2 write SetScalemY2; // (0);
    property ScalecmSimpleMargin: double read GetScalecmSimpleMargin write SetScalecmSimpleMargin; // (0);
    property ScalecmMarginTop: double read GetScalecmMarginTop write SetScalecmMarginTop; // (0);
    property ScalecmMarginBottom: double read GetScalecmMarginBottom write SetScalecmMarginBottom; // (0);
    property ScalecmMarginLeft: double read GetScalecmMarginLeft write SetScalecmMarginLeft; // (0);
    property ScalecmMarginRight: double read GetScalecmMarginRight write SetScalecmMarginRight; // (0);
    property ScalemWidth: double read GetScalemWidth write SetScalemWidth; // (1); // (2); // (3);
    property ScalemHeight: double read GetScalemHeight write SetScalemHeight; // (1); // (2); // (3);
    property ScalemWidthX: double read GetScalemWidthX write SetScalemWidthX; // (1);
    property ScalemHeightY: double read GetScalemHeightY write SetScalemHeightY; // (1);
    property ScalemLength: double read GetScalemLength write SetScalemLength; // (1); // (3);
    property ScalemRadius: double read GetScalemRadius write SetScalemRadius; // (1); // (2); // (3);
    property LineAngle: double read GetLineAngle write SetLineAngle; // (1); // (3);
    property Designing: boolean read GetDesigning write SetDesigning; // (0);
    property FontMode: boolean read GetFontMode write SetFontMode; // (1);
    property Selected: boolean read GetSelected; // (0);
    property Smoothing: boolean read GetSmoothing write SetSmoothing; // (2);
    property AsCirclePie: boolean read GetAsCirclePie write SetAsCirclePie; // (2);
    property ShowPolygonLines: boolean read GetShowPolygonLines write SetShowPolygonLines; // (2);
    property ClosedPolygon: boolean read GetClosedPolygon write SetClosedPolygon; // (2);
    property CrossRect: boolean read GetCrossRect write SetCrossRect; // (2);
    property CircleAlpha: double read GetCircleAlpha write SetCircleAlpha; // (0);
    property PositionAlpha: double read GetPositionAlpha write SetPositionAlpha; // (1);
    property CircleBeta: double read GetCircleBeta write SetCircleBeta; // (0);
    property ArrowA: double read GetArrowA write SetArrowA; // (1);
    property ArrowB: double read GetArrowB write SetArrowB; // (1);
    property DimensionA: double read GetDimensionA write SetDimensionA; // (1);
    property DimensionB: double read GetDimensionB write SetDimensionB; // (1);
    property DimensionVersatz: double read GetDimensionVersatz write SetDimensionVersatz; // (1);
    property PosDiameter: double read GetPosDiameter write SetPosDiameter; // (1);
    property PosQuadratSize: double read GetPosQuadratSize write SetPosQuadratSize; // (3);
    property ScaleCMDistribution: double read GetScaleCMDistribution write SetScaleCMDistribution; // (1); // (3);
    property OffsetX: double read GetOffsetX write SetOffsetX; // (1);
    property OffsetY: double read GetOffsetY write SetOffsetY; // (1);
    property ArrowAlpha: double read GetArrowAlpha write SetArrowAlpha; // (1);
    property HatchFrequency: double read GetHatchFrequency write SetHatchFrequency; // (2);
    property TextAlpha: double read GetTextAlpha write SetTextAlpha; // (1);
    property Angle: double read GetAngle write SetAngle; // (0);
    property ArrowAlign: TArrowAlign read GetArrowAlign write SetArrowAlign; // (1);
    property Text: string read GetText write SetText; // (1); // (3);
    property Caption: string read GetCaption write SetCaption; // (1);
    property OwnerText: string read GetOwnerText write SetOwnerText; // (1);
    property Seite: string read GetSeite write SetSeite; // (1);
    property PenMMWidth: double read GetPenMMWidth write SetPenMMWidth; // (0);
    property Dimension: TDimensionType read GetDimension write SetDimension; // (1);
    property DimensionStyle: TDimensionStyle read GetDimensionStyle write SetDimensionStyle; // (1);
    property DimensionOrientation: TDimensionOrientation read GetDimensionOrientation write SetDimensionOrientation; // (1);
    property DimensionAlignLeft: TDimensionAlign read GetDimensionAlignLeft write SetDimensionAlignLeft; // (1);
    property DimensionAlignRight: TDimensionAlign read GetDimensionAlignRight write SetDimensionAlignRight; // (1);
    property PosAlign: TPosAlign read GetPosAlign write SetPosAlign; // (1);
    property PositionAlign: TPositionAlign read GetPositionAlign write SetPositionAlign; // (1);
    property TextAlign: TTextAlign read GetTextAlign write SetTextAlign; // (1);
    property OddHatchPenStyle: TPenStyle read GetOddHatchPenStyle write SetOddHatchPenStyle; // (2);
    property EvenHatchPenStyle: TPenStyle read GetEvenHatchPenStyle write SetEvenHatchPenStyle; // (2);
    property SchnittTriangleWidth: double read GetSchnittTriangleWidth write SetSchnittTriangleWidth; // (1);
    property SchnittAlign: TSchnittAlign read GetSchnittAlign write SetSchnittAlign; // (1);
    property SchnittFilledTriangle: boolean read GetSchnittFilledTriangle write SetSchnittFilledTriangle; // (1);
    property TextA: string read GetTextA write SetTextA; // (1);
    property TextB: string read GetTextB write SetTextB; // (1);
    property HintStyle: TCornerStyle read GetHintStyle write SetHintStyle; // (1);
    property KoteTriangleWidth: double read GetKoteTriangleWidth write SetKoteTriangleWidth; // (1);
    property KoteAlign: TSchnittAlign read GetKoteAlign write SetKoteAlign; // (1);
    property KoteFilledTriangle: boolean read GetKoteFilledTriangle write SetKoteFilledTriangle; // (1);
    property AspectRatio: boolean read GetAspectRatio write SetAspectRatio; // (1);
    property ExtraListEnabled: boolean read GetExtraListEnabled write SetExtraListEnabled; // (1); // (3);
    property TopReinforcement: boolean read GetTopReinforcement write SetTopReinforcement; // (3);
    property NEckCount: integer read GetNEckCount write SetNEckCount; // (2);
    property HelpPolygonDistribution: integer read GetHelpPolygonDistribution write SetHelpPolygonDistribution; // (2);
    property StabPunktFilled: boolean read GetStabPunktFilled write SetStabPunktFilled; // (3);
    property NEckScalemA: double read GetNEckScalemA write SetNEckScalemA; // (2);
    property ScalemmFlange: double read GetScalemmFlange write SetScalemmFlange; // (2);
    property ScalemmThickness: double read GetScalemmThickness write SetScalemmThickness; // (2);
    property PropertySelected: boolean read GetPropertySelected write SetPropertySelected; // (0);
    property BrushColor: TColor read GetBrushColor write SetBrushColor; // (1); // (2);
    property BrushStyle: TBrushStyle read GetBrushStyle write SetBrushStyle; // (2);
    property Profil: string read GetProfil write SetProfil; // (2);
    property Scale: TScale read GetScale write SetScale; // (0);
    property BoundRect: TFloatRectEx read GetBoundRect; // (1); // (2); // (3);
    property HaveBoundRect: boolean read GetHaveBoundRect; // (1); // (2); // (3);
    property SimpleMargin: double read GetSimpleMargin; // (0);
    property Margin: TMargin read GetMargin; // (0);
  end;

implementation

end.

BadenPower 9. Jun 2015 14:36

AW: Setter mehrfach überschreiben.
 
Zitat:

Zitat von Bjoerk (Beitrag 1304704)
Es ist nur so, daß die einzelnen Klassen, die davon abgeleitet sind, nicht jede Methode bzw. jede Property haben.

Ja, und genau darum erhälst Du die Warnung des Compilers.

Mikkey 9. Jun 2015 14:40

AW: Setter mehrfach überschreiben.
 
Das ist eigentlich nicht der Sinn, der hinter abstrakten Klassen steckt.

Wenn ich eine Basisklasse mit quasi-abstrakten Methoden habe, die nur wahlfrei überschrieben werden können, definieren ich keine abstrakten Methoden sondern echte, die als einzige Anweisung das Werfen einer Ausnahme enthalten.
Delphi-Quellcode:
Procedure Basisklasse.SetNotExistentValue(value: Integer);
begin
   raise ENotImplemented.Create("SetNotExistentValue");
end;

himitsu 9. Jun 2015 14:59

AW: Setter mehrfach überschreiben.
 
Zitat:

Zitat von stahli (Beitrag 1304703)
Dann lag ich wohl falsch... :oops:
Ich dachte, man darf die Methode dann nur nicht aufrufen...

Wenn, dann kommt eine EAbstract-Exception
und vorher "warnt" der Compiler, daß es eventuell knallen könnte, da er dort natürlich nicht weiß, ob es aufgerufen wird.

Zitat:

Zitat von Mikkey (Beitrag 1304708)
die als einzige Anweisung das Werfen einer Ausnahme enthalten.

Genau das macht Delphi doch auch, nur daß man nicht auf uns/mich hört und dort keine schöne Exception liefet, mit Quellangabe. :cry: (kann man zwar selber via RTTI nachrüsten, aber ist dennoch blöd)

Bjoerk 9. Jun 2015 15:47

AW: Setter mehrfach überschreiben.
 
Ja, gebe euch Recht. Hab aus den abstrakten virtuelle gemacht, die Codevervollständung gedrückt und den Source so ergänzt.

Delphi-Quellcode:
procedure TMemoForm.Button2Click(Sender: TObject);
var
  I: integer;
  S0, S1, S2: string;
  C: char;
begin
  C := '''';
  for I := 0 to MemoA.Lines.Count - 3 do
  begin
    S0 := Trim(MemoA.Lines[I]);
    S1 := Trim(MemoA.Lines[I + 1]);
    S2 := Trim(MemoA.Lines[I + 2]);
    if (S0 = 'begin') and (S1 = '') and (S2 = 'end;') then
      MemoA.Lines[I + 1] := ' raise Exception.Create(' + C +'abstract Method' + C + ');';
  end;
end;

BadenPower 9. Jun 2015 15:52

AW: Setter mehrfach überschreiben.
 
Blödsinn geschrieben, da auf falschen Post bezogen.

Bjoerk 9. Jun 2015 16:13

AW: Setter mehrfach überschreiben.
 
Nee, was du in #10 geschrieben hast war genau richtig!?

BadenPower 9. Jun 2015 16:29

AW: Setter mehrfach überschreiben.
 
Zitat:

Zitat von Bjoerk (Beitrag 1304718)
Nee, was du in #10 geschrieben hast war genau richtig!?

Ging nicht um #10, sondern um den "original Text" meines Posts #14, welchen ich editiert habe.

Weil:

Ich habe in #14 schon etwas geschrieben gehabt und bin dort nochmals auf die Verwendung von "abstract" eingegangen und habe dann aber bemerkt, dass der Post in #11 auf den ich mich bezog gar nicht von Dir war, sondern von Mikkey.

Somit war das, was ich geschrieben hatte, nicht im richtigen Kontext und daher Blödsinn.

Bjoerk 9. Jun 2015 18:00

AW: Setter mehrfach überschreiben.
 
In den Zusammenhang stellt sich für mich die Frage, ob es möglich ist, eine Faktory aus 3 unterschiedlichen Klassen zu erstellen. Falls da ja jemand irgendeine Chance sieht, mach in nen neuen Thread auf.

DeddyH 9. Jun 2015 18:32

AW: Setter mehrfach überschreiben.
 
Meiner Meinung nach sieht das schon aufgrund der Vielzahl an Properties und Methoden arg nach Gottklasse aus. Evtl. wäre es besser, das Design noch einmal zu überdenken. Abstrakte Methoden verwendet man z.B., wenn jede abgeleitete Klasse sie implementieren muss, es aber auf dieser Hierarchiestufe noch keine Gemeinsamkeit gibt außer der Methode an sich. So kann sich z.B. jedes Fahrzeug bewegen (da dies ja sein essentieller Sinn ist), aber jedes anders (Flugzeuge fliegen, Landfahrzeuge fahren, Wasserfahrzeuge schwimmen). Auf der Stufe TFahrzeug macht es also durchaus Sinn, eine abstrakte Methode "Bewege" einzuführen. Erst wenn es so "speziell" wird, dass es einen gemeinsamen Nenner gibt, erfolgt dann die (erste) Implementation, die auf weiteren Stufen ggf. noch überschrieben werden kann. Zu Deiner Factory: wäre es nicht sinnig, hier Interfaces einzuführen? Je weiter man sich durch den Klassenbaum nach unten bewegt, desto mehr Interfaces werden dann eben implementiert. Ob eine Klasse ein bestimmtes Interface implementiert, lässt sich ja erfragen.

Just my 2 cents.

Bjoerk 9. Jun 2015 19:12

AW: Setter mehrfach überschreiben.
 
Ja, ist sehr aufgebläht. Diese Klasse hab ich eigentlich nur deshalb eingeführt um keine Fehler zu machen (auf protected-Symbol TWerkzeug.xyz kann nicht zugegriffen werden) und um einen gemeinsamen Vorfahren zu haben.

Ableiten wär mir eigentlich lieber als interfaces?

DeddyH 9. Jun 2015 19:38

AW: Setter mehrfach überschreiben.
 
Ableiten ginge auch, dann prüft man eben nicht, ob ein bestimmtes Interface imlpementiert, sondern ob das Objekt von einem bestimmten Klassentyp ist.

Bjoerk 10. Jun 2015 07:47

AW: Setter mehrfach überschreiben.
 
Ich hab diese fürchterliche Basisklasse geschreddert (nicht nur gelöscht). Die bringt überhaupt nichts null nothing gar nichts. Ich habe 3 Kategorien von geometrischen Objekten, die ich eh immer abfragen muß?

Beispiel:
Delphi-Quellcode:
procedure TDrawPadProperties.SetProperties(Item: TWerkzeug0);
var
  Item1: TWerkzeug1;
  Item2: TWerkzeug2;
  Item3: TWerkzeug3;
begin
  SetProperties0(Item);
  if Item is TWerkzeug1 then
  begin
    Item1 := TWerkzeug1(Item);
    SetProperties1(Item1);
  end
  else
    if Item is TWerkzeug2 then
    begin
      Item2 := TWerkzeug2(Item);
      SetProperties2(Item2);
    end
    else
    begin
      Item3 := TWerkzeug3(Item);
      SetProperties3(Item3);
    end;
end;

Mikkey 10. Jun 2015 07:56

AW: Setter mehrfach überschreiben.
 
Nö, so wird ein Schuh draus:

Delphi-Quellcode:
Procedure TWerkzeug0.SetProperties();
begin
    ...
end;

Procedure TWerkzeug1.SetProperties();
begin
    inherited SetProperties();
    ...
end;
...
Sonst baust Du ja die Logik nach, die Dir durch OOP zur Verfügung gestellt wird.

Dejan Vu 10. Jun 2015 08:24

AW: Setter mehrfach überschreiben.
 
Wieso schreibst Du dir keinen WerkzeugPropertySetter und eine Factory, die Dir zu dem Werkzeug ('Item') die passende Klasse liefert, welche dann die Daten setzt. Wenn bei deinem Ansatz nämlich noch ein TWerkzeug4 hinzukommt, musst Du deinen Code anpassen, und das wäre dann so gar nicht OCP.
Delphi-Quellcode:
Type
  IWerkzeugPropertySetter = interface
    SetProperties(Item : TWerkzeug0);
  end;

procedure TDrawPadProperties.SetProperties(Item: TWerkzeug0);
var
  propertySetter : IWerkzeugPropertySetter;

begin
  propertySetter := WerkzeugPropertySetterFactory.Create(Item);
  propertySetter.SetProperties(Item);
end;
Leider musst Du in den einzelnen Setterklassen dann dein 'Item' immernoch konkret auf TWerkzeugX casten, aber da Du keine Generics benutzt, bleibt dir hier dann wohl nichts anderes übrig. Mit Generics würde das so aussehen (so ungefähr jedenfalls)

Delphi-Quellcode:
Type
  IWerkzeugPropertySetter<T : TWerkzeug0> = interface
    SetProperties(Item : T);
  end;

  WerkzeugPropertySetterFactory = class
    Function Create<T : TWerkzeug0> (Item : T) : IWerkzeugPropertySetter<T>;
  End;

procedure TDrawPadProperties.SetProperties<T:TWerkzeug0>(Item: T);
var
  propertySetter : IWerkzeugPropertySetter<T>;

begin
  propertySetter := WerkzeugPropertySetterFactory.Create<T>(Item);
  propertySetter.SetProperties(Item);
end;
Und das wäre dann typsicher. Wenn nun ein 4. Werkzeug hinzukommst, schreibst Du eine neue Klasse dafür und registrierest diese in der Factory.

Bjoerk 10. Jun 2015 13:06

AW: Setter mehrfach überschreiben.
 
Weil der Typ TWerkzeug0 so was Ähnliches wie TCustomControl ist. Wirklich viel macht TWerkzeug0 noch nicht. Ich hab jetzt mal das vorbereitet. Ist an manchen Stellen eine Arbeitserleichterung. Wobei mich immer wundert daß man in Delphi "Bauer := TDame.Create" machen kann.
Delphi-Quellcode:
  TWerkzeugFactory = class
  private
    FTyp: TGraphicTyp;
    FWerkzeug: TWerkzeug0;
    procedure SetTyp(const Value: TGraphicTyp);
    procedure DoCreate;
    procedure DoDestroy;
    function GetWerkzeug1: TWerkzeug1;
    function GetWerkzeug2: TWerkzeug2;
    function GetWerkzeug3: TWerkzeug3;
    function GetIsWerkzeug1: boolean;
    function GetIsWerkzeug2: boolean;
    function GetIsWerkzeug3: boolean;
  public
    property Typ: TGraphicTyp read FTyp write SetTyp;
    property Werkzeug: TWerkzeug0 read FWerkzeug;
    property Werkzeug1: TWerkzeug1 read GetWerkzeug1;
    property Werkzeug2: TWerkzeug2 read GetWerkzeug2;
    property Werkzeug3: TWerkzeug3 read GetWerkzeug3;
    property IsWerkzeug1: boolean read GetIsWerkzeug1;
    property IsWerkzeug2: boolean read GetIsWerkzeug2;
    property IsWerkzeug3: boolean read GetIsWerkzeug3;
    destructor Destroy; override;
  end;

{ TWerkzeugFactory }

destructor TWerkzeugFactory.Destroy;
begin
  DoDestroy;
  inherited;
end;

procedure TWerkzeugFactory.DoCreate;
begin
  if Util_IsWerkzeug1(FTyp) then
    FWerkzeug := TWerkzeug1.Create
  else
    if Util_IsWerkzeug2(FTyp) then
      FWerkzeug := TWerkzeug2.Create
    else
      if Util_IsWerkzeug3(FTyp) then
        FWerkzeug := TWerkzeug3.Create
      else
        FWerkzeug := TWerkzeug0.Create;
end;

procedure TWerkzeugFactory.DoDestroy;
begin
  if Assigned(FWerkzeug) then
  begin
    FWerkzeug.Free;
    FWerkzeug := nil;
  end;
end;

procedure TWerkzeugFactory.SetTyp(const Value: TGraphicTyp);
begin
  DoDestroy;
  FTyp := Value;
  DoCreate;
end;

function TWerkzeugFactory.GetIsWerkzeug1: boolean;
begin
  Result := FWerkzeug is TWerkzeug1;
end;

function TWerkzeugFactory.GetIsWerkzeug2: boolean;
begin
  Result := FWerkzeug is TWerkzeug2;
end;

function TWerkzeugFactory.GetIsWerkzeug3: boolean;
begin
  Result := FWerkzeug is TWerkzeug3;
end;

function TWerkzeugFactory.GetWerkzeug1: TWerkzeug1;
begin
  if IsWerkzeug1 then
    Result := TWerkzeug1(FWerkzeug)
  else
    Result := nil;
end;

function TWerkzeugFactory.GetWerkzeug2: TWerkzeug2;
begin
  if IsWerkzeug2 then
    Result := TWerkzeug2(FWerkzeug)
  else
    Result := nil;
end;

function TWerkzeugFactory.GetWerkzeug3: TWerkzeug3;
begin
  if IsWerkzeug3 then
    Result := TWerkzeug3(FWerkzeug)
  else
    Result := nil;
end;

DeddyH 10. Jun 2015 13:13

AW: Setter mehrfach überschreiben.
 
Den Sinn dieser Factory verstehe ich ehrlich gesagt nicht. Kommt noch eine Ableitung hinzu, muss auch die Factory geändert werden, damit sie die entsprechende Klasseninstanz liefern kann, das bringt irgendwie nix.

Bjoerk 10. Jun 2015 13:20

AW: Setter mehrfach überschreiben.
 
Ei, ich hann gemennt.. :)

stahli 10. Jun 2015 13:21

AW: Setter mehrfach überschreiben.
 
Schreib doch mal, was Du da vor hast.
Willst Du nur eine Werkzeuginstanz?

Sollen das sichtbare Controls werden?

Was soll das Projekt machen und was die Fabrik?

Bjoerk 10. Jun 2015 14:29

AW: Setter mehrfach überschreiben.
 
Ok. Also: Ich habe 3 Klassen ala TShape (TWerkzeug1,2,3). Jede TWerkzeug Class kann so 15-25 Figuren zeichnen. Alles was in den Shapes gleich ist, befindet sich in der Basisklasse TWerkzeug0. Der User wählt mit dem Speedbutton eines von ca. 70 zu zeichnenden Objecte aus. Je nachdem in welcher Klasse das Objekt gezeichnet wird, muß also Werkzeug1,2,3.Draw ausgeführt werden. Draw befindet sich abstract in TWerkzeug0 und wird von Werkzeug1,2,3 überschrieben. Ist somit kein Problem. Das ist aber bei den Variablen nicht so. Deshalb hatte ich die Idee mit der aufgeblähten Klasse von #9. Davon wäre TWerkzeug0 abgeleitet gewesen. Alle Properties (Getter/Setter) würden überschrieben. Zurzeit muß ich explizit auf 1 oder 2 oder 3 prüfen. Zum Beispiel: TWerkzeug2 hat eine Property Polygon, Werkzeug1 und Werkzeug3 nicht. Ich muß also prüfen,

wenn Polygon -> dann TWerkzeug2 -> dann FWerkzeug2.Polygon.Add(X, Y).

Dieses Prüfen ob 1 2 oder 3 ist aber nicht so prickelnd und sehr viel Tipparbeit (gewesen). Und was ist wenn es mal 4 oder 5 Werkzeugkategorien werden sollten (wurde ja schon angesprochen).

Ich hatte im Bezug auf dieses Programm schon mehrere Threads hier und da wurde mir immer (oder öfter) eine Faktory empfohlen. Anscheinend hab ich das noch nicht ausreichend kapiert bzw. den Sinn einer Faktory nicht ganz verstanden.

Ich suche eigentlich nur ein elegantes Handling für diese 3 Klassen.

DeddyH 10. Jun 2015 14:54

AW: Setter mehrfach überschreiben.
 
Ohne die Klassen zu kennen: wäre es nicht möglich, eine Basis-Methode zu deklarieren (kann auch abstrakt sein) oder ersatzweise eine Property, die die abgeleiteten Klassen dann eben unterschiedlich behandeln? Statt also von außen Dings.Polygon.Add aufzurufen, wird eben der Weg über Basisklasse.AddPoint(X,Y) gegangen. AddPoint wird dabei unterschiedlich behandelt, aber eben nur intern, den Aufrufer schert das nicht.

stahli 10. Jun 2015 15:06

AW: Setter mehrfach überschreiben.
 
Genau.

Was die Controls zeichnen geht von außen niemanden etwas an.
Ob sie intern ein Polygon verwalten oder mehrere Farben oder Textumbrüche ist normalerweise Privatsache der spezialisierten Klasse.

Nach außen musst Du ja nur das öffentlich machen, was die Umgebung Deiner Werkzeuge interessiert.

Du kannst Deine Basisklasse ja rel. klein halten:

Delphi-Quellcode:
TBaseClass = class
public
  procedure Paint; virtual;
end;
und in Deinen abgeleiteten Klassen führst Du private Detaileigenschaften ein:

Delphi-Quellcode:
TClassA = class(TBaseClass)
private
  Polygon...
public
  procedure Paint; override;
end;

TClassB = class(TBaseClass)
private
  Text...
public
  procedure Paint; override;
end;

Die Daten musst Du natürlich ggf. von außen klassenspezifisch zuweisen, aber die Basisklasse muss ja nicht alle Varianten kennen sondern nur die einheitlichen Eigenschaften.


Eine Factory wird Dir hier nichts bringen. Ich denke, Du musst die Klasseneigenschaften nur besser nach tatsächlichen Aufgaben trennen.

Müssen Deine Klassen noch etwas anderes machen, als sich zu zeichnen?

Bjoerk 10. Jun 2015 15:12

AW: Setter mehrfach überschreiben.
 
DeddyH, ich denke mal das wäre sicherlich möglich. Diese Idee hatte ich zum Beispiel noch nicht. Thanx.

Bjoerk 10. Jun 2015 15:18

AW: Setter mehrfach überschreiben.
 
stahli, in Bezug auf gleiche Methoden hab ich das so. Mir geht's jetzt noch um die Properties. Da hat DeddyH ja einen Vorschlag gemacht. AddPoint könnte jede Klasse vertragen.

Dejan Vu 10. Jun 2015 19:23

AW: Setter mehrfach überschreiben.
 
Wieso schreibt man nicht einfach ein Werkzeug pro Figur? Dann fallen alle Fragen weg.
Ich hab ne TFigur.
Wenn ich sie zeichnen will, nehme ich einen TFigurPainter, bzw. ne abgeleitete Klasse, oder ne Klasse, die das IFigurPainter-Interface implementiert

Und wenn ich die TFigur speichern will, dann nehme ich ... einen TFigurWriter...
Und wenn ich die TFigur laden will, dann ...
Und wenn ich die TFigur drucken will, dann ...
Und wenn ich die TFigur backen will, dann ...

usw. usw.
Daraus kann man dann sogar eine Factory-Factory bauen:

Delphi-Quellcode:
Procedure TuWasMitDerFigur (DieAktion : FigurAktion; Figur : TFigure);
Var
  Aktion : TFigurAktion;
  AktionFactory : TFigureAktionFactory;

Begin
  AktionFactory := TFigurAktionFactoryFactory.CreateFactory(DieAktion);
  Aktion := AktionFactory.Create(Figur);
  Aktion.FühreAus(Figur);
End;
Die TFigurAktionFactoryFactory liefert eine TFigurAktionFactory, je nach inhalt von 'DieAktion' (Laden,Speichern,Zeichnen,Drucken,Backen).

Und die AktionFactory liefert die ensprechende Aktionsklasse für die Figur.

Und die Aktion führt die Aktion aus :stupid:

Diesen Code musst Du nie wieder ändern. Du registrierst nur weitere Figuren, Aktionen und deklarierst neue FigurAktion('Tanzen' z.B. oder.. äh.. heiraten, keine Ahnung). D.h.: Du änderst den Code nie wieder (OCP).

Bjoerk 10. Jun 2015 20:53

AW: Setter mehrfach überschreiben.
 
Du machst mir echt Laune. Wirfst mal so eben die Arbeit von ca. 2 Jahren weg.:) Wenn man ein Figur Line, dann hat man auch ein schnell einen Pfeil oder einen Hint. Wenn man einen Kreis hat dann auch schnell eine Ellipse, einen Arc, eine Kreislinie ect. Das Zusammenfassen ist in schon in Ordnung so (Siehe auch TShape). Das eigentliche Zeichen wird oft auch weiter delegiert. Darum sollte es hier aber nicht gehen. Das override von Methoden ist nicht das Problem hier. Schau dir mal den letzten Post von DeddyH an. Genauso bräuchte ich das auch für möglichst viele Props. Daran habe ich aber beim Design nicht gedacht. Zur Zeit überlege ich, analog den Werkzeugklassen Datenklassen zu erstellen, damit gings vermutlich auch.

Bjoerk 10. Jun 2015 21:05

AW: Setter mehrfach überschreiben.
 
Zitat:

Zitat von stahli (Beitrag 1304803)
[..] Müssen Deine Klassen noch etwas anderes machen, als sich zu zeichnen?

Ja, die Klassen machen mehr, viel mehr. Längenermittlung, Gewichtermittlung, Stücklisten, Schnittpunkte, Fangpunkte, diverse Rucksackprobleme lösen, OI, dxf/dwg Parser ect.. Das erledigen weitere Klassen in Verbindung mit dem Object und der Liste. Das Programm ist nicht ganz einfach, ehrlich gesagt bin ich froh daß ich’s überhaupt hingekriegt hab..

stahli 10. Jun 2015 21:17

AW: Setter mehrfach überschreiben.
 
Dann hatte ich vermutlich eine Anwendung mit meiner Turniersoftware (siehe Homepage).
Ich hatte dazu Datenklassen und visuelle Controls voneinander getrennt.

Die Datenklassen haben die gesamte Logik und Daten gekapselt - also das eigentliche Projekt und den Turnierzustand abgebildet.

Die Controls konnten dann ein Datenobjekt referenzieren (TvSpieler z.B. einen TdSpieler).
So kann man gut unterscheiden, was jetzt für die Darstellung umgesetzt werden muss und was für die Datenverarbeitung.

Ein Framework hat dabei noch zusätzlich geholfen. Wenn z.B. ein TvControl doppelt geklickt oder evtl. Enter gedrückt wurde, dann hat das Framework untersucht, was dort für eine Datenklasse referenziert wird und welches Formular für diese Klasse zuständig ist und hat dieses (wenn eines gefunden wurde) gleich geöffnet und ein Databinding an die Controls durchgeführt.

Die Trennung von Daten und GUI kann ich UNBEDINGT empfehlen.
Wenn Du Dir dann noch etwas aufbaust, dass Dir bei der Datenbindung von der GUI an die Daten hilft (oder die GUI anhand der Datensituation aufbaut), dann sollte das eine sehr übersichtliche Arbeitsweise ergeben.

Natürlich macht das erst mal Arbeit, aber etwas fertiges liefert Delphi ja nicht mit.

Dejan Vu 11. Jun 2015 03:06

AW: Setter mehrfach überschreiben.
 
Zitat:

Zitat von Bjoerk (Beitrag 1304825)
Wenn man ein Figur Line, dann hat man auch ein schnell einen Pfeil oder einen Hint. Wenn man einen Kreis hat dann auch schnell eine Ellipse, einen Arc, eine Kreislinie ect.

Also das widerspricht ja nicht meinem Ansatz. Die Figuren können voneinander abgeleitet sein (Achtung! Square/Rectangle-Problematik), aber ein Painter macht eben genau eine einzige Sache. Ein Pfeil-Painter kann ja einen Linien-Painter verwenden, aber er muss nicht unbedingt von ihm ableiten. Nebenbei: Ein Pfeil ist ja auch nicht unbedingt eine Linie.

Auf diese Weise bleiben die Klassen klein. Und Du hast kein Ableitungskuddelmuddel. Denn das hast Du, sonst würdest Du die Frage hier nicht stellen.

Diese Ableitungsmanie ist ein Irrweg, wenn Du mich fragst. Interfaces, Algorithms und Delegates sind ein anderer Weg, gemeinsames Verhalten zu ordnen. So könnten deine Painter komplett unabhängig voneinander sein und nur das IShapePainter-Interface implementieren.

Bjoerk 11. Jun 2015 11:34

AW: Setter mehrfach überschreiben.
 
Du hast mich immer noch nicht verstanden. Was machst du, wenn du ein rundes Control hast, aber TCustomControl keine Radius Prop hat, dein Objectinspector aber ein TCustomControl erwartet? Entweder du kastet dich im OI zu tode oder du führst eben abtsracte Getter und Setter schon auf dieser Ebene ein. Oder du machst es wie DeddyH vorgeschlagen hat über eine allgemeine (hier) AddFloat und überschreibst die. Eine Ableitungsmanie kann ich darin nicht erkennen..

stahli 11. Jun 2015 11:48

AW: Setter mehrfach überschreiben.
 
Eine Überlegung dazu:

Wenn das Problem EIGENTLICH der Objektinspektor ist, dann musst Du den verbessern oder umbauen.
Der OI darf einfach nicht nur ein CustomControl erwarten, sondern er muss mit allen möglichen Klassen klar kommen.

Grundsätzlich kann man ja alle Propertys einer Klasse ermitteln und im OI genau diese Propertys binden. Mit der neuen RTTI ab D2010 wüsste ich, wie das geht - mit D2007 nicht auf Anhieb.

Wenn das zu komplex oder nicht zielführend/ausreichend ist, kannst Du pro Klasse auch eine Property-Tabelle ablegen (z.B. als XML).
Da kannst Du für TRoundTool hinterlegen, dass der Radius gebunden werden soll und zwar mit 3 Nachkommastellen.
Wenn der OI einen Apfel binden soll, dann steht in der XML, dass er den Zuckergehalt binden soll.

So könntest Du das Problem m.E. geschickt auslagern ohne Deine Klassen zu sehr zu verbiegen.

Die Klassen könnten sich darauf beschränken, was sie selbst brauchen und müssen sich nicht noch um die Umgebung kümmern.

himitsu 11. Jun 2015 12:24

AW: Setter mehrfach überschreiben.
 
Der OI nur geht auf Published-Property und die können auch über die "alte" RTTI ermittelt werden.


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:19 Uhr.
Seite 1 von 2  1 2      

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