我認為 DELPHI 語言通過屬性方法和清晰的 getter 和 setter 函式提供了一個非常清晰和漂亮的資料封裝實作。
我想通過 getter 和 setter 函式訪問類字串串列 strlst 。代碼示例中的選項 #1 按預期作業正常,但呼叫 Stringlist.Commatext 函式的選項 #2 實際上不起作用。
這是一個 DELPHI 錯誤還是我錯過了關于類設計的一些東西?
目標:在不創建外部 Tstringlist 類的情況下填充類 stringlist,只需傳遞逗號文本。
program Project2;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils, classes;
type
TSimpleClass = class
FStrlst: TStringList;
private
procedure SetStrList(const Value: TStringList);
public
constructor Create;
property strlst: TStringList read FStrlst write SetStrList;
end;
{ TSimpleClass }
constructor TSimpleClass.Create;
begin
inherited;
FStrlst := TStringList.Create;
end;
procedure TSimpleClass.SetStrList(const Value: TStringList);
var
i: Integer;
begin
Writeln('class getter / setter function is called ');
for i := 0 to Value.Count - 1 do
begin
FStrlst.Add(Value[i]);
end;
writeln ('content of internal strlist : ' FStrlst.CommaText )
end;
begin
var
aSimpleClass: TSimpleClass;
var
testLst: TStringList;
try
aSimpleClass := TSimpleClass.Create;
try
// option #1 is working
testLst:=TStringList.Create;
testLst.CommaText := 'a,b,c';
aSimpleClass.strlst := testLst;
// option #2 not working ... this code should also call the
// setter function
aSimpleClass.strlst.commatext := 'd,e,f';
finally
aSimpleClass.Free;
end;
writeln ('done sample code !');
Readln;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
cmd 行視窗示例輸出
此示例代碼的輸出
uj5u.com熱心網友回復:
這是一個 DELPHI 錯誤還是我錯過了關于類設計的一些東西?
不,這不是 Delphi 錯誤,而是您的誤解。您說“未呼叫屬性、getter 和 setter 函式”,我知道您指的是 .getter 和 setter aSimpleClass.strlst。
您已為 定義了直接讀取訪問(of FStrLst)TSimpleClass.strlst,因此在讀取時無需呼叫 getter(如在 中// option #2),并且aSimpleClass.strlst直接參考FStrLst。
的CommaText屬性TStringList有自己的設定器,它被呼叫// option #2
編輯
或者,如果您的意圖是根本不公開TStringList,而只是公開其CommaText屬性,則如下所示:
確保TStringList是私有的,以及 的 getter 和 setter CommaText,然后添加屬性CommaTxt
TSimpleClass
private
FStrlst: TStringList;
...
function GetCommaText: string;
procedure SetCommaText(s: string);
public
property CommaTxt: string read GetCommaText write SetCommaText;
...
end;
實作 getter 和 setter:
function TSimpleClass.GetCommaText: string;
begin
result := FStrlst.CommaText;
end;
procedure TSimpleClass.SetCommaText(s: string);
begin
FStrLst.CommaText := s;
end;
現在您可以訪問該CommaTxt屬性而無需公開TStringList.
uj5u.com熱心網友回復:
您option #2不觸發 setter 方法的原因是因為您option #2沒有為您分配任何值,strlst而是與上述屬性回傳的物件進行互動。
當您呼叫aSimpleClass.strlst.commatext := 'd,e,f';接下來會發生什么時,您會看到:
strlst正在呼叫屬性的getter 方法以回傳對 TStringList 物件(由屬性定義的物件型別)的參考- 然后將 的字串值
d,e,f分配給ComaText屬于由您的屬性 getter 方法回傳其參考的字串串列的屬性。
現在,如果此時作為您的類的一部分的 TStringList 仍未創建,則會引發訪問沖突,因為您將嘗試訪問不存在的物件的屬性。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/402524.html
標籤:
