AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Objekt innerhalb Klasse nach außen hin "ReadOnly"

Objekt innerhalb Klasse nach außen hin "ReadOnly"

Ein Thema von Rob09 · begonnen am 10. Apr 2011 · letzter Beitrag vom 11. Apr 2011
Antwort Antwort
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.399 Beiträge
 
Delphi 12 Athens
 
#1

AW: Objekt innerhalb Klasse nach außen hin "ReadOnly"

  Alt 11. Apr 2011, 06:22
Oder eine weitere Klasse (quasi so wie beim Interface), welche nur die gewünschten Propertry und das eine Objekt enthält.
Im Private/Protected-Abschnitt dann noch öffentlich ein Property zum enthaltenen Objekt.

Wenn beide Klassen Die Kapsel-Klasse und deine Basisklasse in der selben Unit deklariert sind, dann kannstr du von deiner Klasse auch auf die privaten Sachen zugreifen und kommst so intern an alles ran. Von außen sieht aber jeder nur das ReadOnly-Zeugs.




Ist das TUnterKlasse von dir geschreiben?
Wenn ja, dann regel das über die Sichtbarkeiten und mach nur das Sichtbar, was auch sichtbar sein soll,
woei es auch so ginge, wie z.B. bei TEdit (für dich) und TCustomEdit (öffentlich).
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Rob09

Registriert seit: 14. Aug 2007
58 Beiträge
 
Delphi 6 Personal
 
#2

AW: Objekt innerhalb Klasse nach außen hin "ReadOnly"

  Alt 11. Apr 2011, 19:29
Zunächst mal vielen Dank an euch alle für die Hilfe!

Habe hier mal zwei mögliche Lösungen implementiert.

Dier erste benutzt ein "Kapsel-Objekt" (namens ExpKlasseRO) innerhalb der OberKlasse, auf das der Benutzer zugreifen darf. Dieses liest alle Eigenschaften vom eigentlichen UnterObjekt ohne Schreibzugriff, wobei der User das eigentliche UnterObjekt gar nicht sieht. Das ist die Lösung, die auf Vorschlag von s.h.a.r.k. entstanden ist. Bitte dabei um Entschuldigung, aber hab alle drei Klassen (TOberKlasse, TExpKlasse, TExpKlasseRO) in ne eigene unit gepackt:

PS: Die Namensgebung stimmt leider nicht mehr mit meiner ursprünglichen Frage überein. Was dort TMyKlasse war, ist jetzt TOberKlasse. Das einstige UnterObjekt vom Typ TUnterKlasse ist jetzt vom Typ TExpKlasse - was dem entpricht.

Delphi-Quellcode:
unit Unit1;

...

implementation

uses
  uTOberKlasse;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  x: TOberKlasse;
begin
  x := TOberKlasse.Create;

  {x.UnterObjektRO.EigenschaftRO := 10;} // geht natürlich nicht, soll ja auch ReadOnly sein

  Button1.Caption := IntToStr(x.UnterObjektRO.EigenschaftRO);
  FreeAndNil(x);
end;

end.
Delphi-Quellcode:
unit uTOberKlasse;

interface

uses
  uTExpKlasse, uTExpKlasseRO;

type

  TOberKlasse = class(TObject)
  private
    FUnterObjekt: TExpKlasse;
    FUnterObjektRO: TExpKlasseRO;
  public
    constructor Create;
    destructor Destroy; override;
    property UnterObjektRO: TExpKlasseRO read FUnterObjektRO;
  end;

implementation

uses
  SysUtils;

constructor TOberKlasse.Create;
begin
  inherited Create;
  FUnterObjekt := TExpKlasse.Create;
  FUnterObjektRO := TExpKlasseRO.Create(FUnterObjekt);
end;

destructor TOberKlasse.Destroy;
begin
  FreeAndNil(FUnterObjektRO);
  FreeAndNil(FUnterObjekt);
  inherited Destroy;
end;

end.
Delphi-Quellcode:
unit uTExpKlasse;

interface

type

  TExpKlasse = class(TObject)
  private
    FEigenschaft: Integer;
    procedure SetEigenschaft(AValue: Integer);
    function GetEigenschaft: Integer;
  public
    property Eigenschaft: Integer read GetEigenschaft write SetEigenschaft;
  end;

implementation

procedure TExpKlasse.SetEigenschaft(AValue: Integer);
begin
  FEigenschaft := AValue;
end;

function TExpKlasse.GetEigenschaft: Integer;
begin
  Result := FEigenschaft;
end;

end.
Delphi-Quellcode:
unit uTExpKlasseRO;

interface

uses
  uTExpKlasse;

type

  TExpKlasseRO = class(TObject)
  private
    FReferenzObjekt: TExpKlasse;
    function GetEigenschaftRO: Integer;
  public
    constructor Create(AReferenzObjekt: TExpKlasse);
    property EigenschaftRO: Integer read GetEigenschaftRO;
  end;

implementation

constructor TExpKlasseRO.Create(AReferenzObjekt: TExpKlasse);
begin
  inherited Create;
  FReferenzObjekt := AReferenzObjekt;
end;

function TExpKlasseRO.GetEigenschaftRO: Integer;
begin
  Result := FReferenzObjekt.Eigenschaft;
end;

end.


Die zweite Lösung ist die mit dem Interface, auf Vorschlag von schlecki.

Delphi-Quellcode:
unit Unit1;

...

implementation

uses
  uTOberKlasse;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  x: TOberKlasse;
begin
  x := TOberKlasse.Create;

  {x.UnterObjektRO.Eigenschaft := 10;} // geht natürlich NICHT, weil bei UnterObjektRO vom Typ IExpInterface ist .Eigenschaft ReadOnly

  Button1.Caption := IntToStr(x.UnterObjektRO.Eigenschaft);
  FreeAndNil(x);
end;

end.
Delphi-Quellcode:
unit uTOberKlasse;

interface

uses
  uTExpKlasse, uIExpInterface;

type

  TOberKlasse = class(TObject)
  private
    FUnterObjekt: TExpKlasse;
    FInterfaceUnterObjekt: IExpInterface;
  public
    constructor Create;
    destructor Destroy; override;
    property UnterObjektRO: IExpInterface read FInterfaceUnterObjekt;
  end;

implementation

uses
  SysUtils;

constructor TOberKlasse.Create;
begin
  inherited Create;
  FUnterObjekt := TExpKlasse.Create;
  FInterfaceUnterObjekt := FUnterObjekt;
end;

destructor TOberKlasse.Destroy;
begin

  // ACHTUNG!

  // entweder dies:
  FInterfaceUnterObjekt := nil;
  // ODER dies:
  {FreeAndNil(FUnterObjekt);}

  // siehe dazu z.B. http://development.mwcs.de/tutinterfaces.html
  // PS: Es entsteht KEIN Speicherleck!

  inherited Destroy;
end;

end.
Delphi-Quellcode:
unit uIExpInterface;

interface

type

  IExpInterface = interface(IInterface)
  ['{5DD93564-1E6D-4D23-9EEE-B6E232CF4D9F}']
    function GetEigenschaft: Integer;
    property Eigenschaft: Integer read GetEigenschaft;
  end;

implementation

end.
Delphi-Quellcode:
unit uTExpKlasse;

interface

uses
  uIExpInterface;

type

  TExpKlasse = class(TInterfacedObject, IExpInterface)
  private
    FEigenschaft: Integer;
    procedure SetEigenschaft(AValue: Integer);
    function GetEigenschaft: Integer;
  public
    property Eigenschaft: Integer read GetEigenschaft write SetEigenschaft;
  end;

implementation

procedure TExpKlasse.SetEigenschaft(AValue: Integer);
begin
  FEigenschaft := AValue;
end;

function TExpKlasse.GetEigenschaft: Integer;
begin
  Result := FEigenschaft;
end;

end.


In jedem Fall ist es der OberKlasse möglich, direkt auf UnterObjekt zuzugreifen und alle beliebigen Schreiboperationen durchzuführen, während der Benutzer, der ein Objekt vom Typ TOberKlasse verwendet, nur die gewünschten Eigenschaften von UnterObjekt innerhalb des OberObjekt auslesen kann, ohne Schreibzugriff. Die erste Variante ist auch geeignet, wenn es sich bei UnterKlasse um eine Klasse handelt, die man nicht selbst implementiert hat (vgl. Anmerkung von himitsu).

Hoffe, das hilft auch anderen weiter. Weitere Optimierungsvorschläge sind gerne erwünscht

Beste Grüße!
Robert

Geändert von Rob09 (12. Apr 2011 um 17:00 Uhr) Grund: Jetzt erst die [DELPHI]-Umgebung entdeckt ;-)
  Mit Zitat antworten Zitat
Rob09

Registriert seit: 14. Aug 2007
58 Beiträge
 
Delphi 6 Personal
 
#3

AW: Objekt innerhalb Klasse nach außen hin "ReadOnly"

  Alt 11. Apr 2011, 19:31
(Thema ist jetzt nicht mehr als offene Frage markiert)
  Mit Zitat antworten Zitat
Antwort Antwort

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 18:19 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz