封装有关问题 以及 复制子类 有关问题 思考良久.
封装问题 以及 复制子类 问题 思考良久.....
自己写的类,直接从OBJECT继承,
当一个类ListManager有一个TLIST链表属性DataList,用来存储数据的时候的情况.
该类有一个Buy(TObj);的方法来加入一个TOBJ的实例到FDATALIST
不过我是这么写的
FDataList.Add(Tobj);
也就是说加到FDataList里的实际只是该OTBJ实例的类引用.并不是把值复制给他.
而实际数据是存储在别的地方,比如其他地方A1.
访问这个类的该TLIST属性的时候.我是这么写的
Result:= FDataList;
这个实际上是返回的该类的私有成员FDATALIST里存在的TOBJ实例所在地址.
也就是说,编码者在这里通过调用该类的TLIST属性 可以直接修改A1里的对应的实例的数据.
总感觉这样好像不符合封装的基本原理
是不是需要把
FDataList.Add(Tobj);
改为:
FNewTobj:= Tobj.Create;
FNewTobj.Assgin(Tobj); (FNewTobj为该类里的一个TOBJ私有域) //这里加的时候可能是任意TOBJ的基类实例 把加入的类实例复制给一个新的TOBJ的私有类实例
FDataList.Add(Tobj);
这样应该可以创建新的数据,而防止操作ListManager类的时候修改到A1里原来的数据.
不过问题又出来了.因为TOBJ是一个虚拟基类
怎么判断加入的是他的哪个子类呢?
加入以后在读取DataList属性的时候读出来的实例的时候能否(DELPHI是用IS判断符)判断出DATALIST里的引用是哪个TOBJ的基类
的实例,或责都是判断成TOBJ的呢?
比如TOBJ.Check,而TOBJ的子类覆盖了OBJ.check
这个时候因为是使用的NewTobj:= Tobj.Create;所以调用ListManage的DATALIST属性访问到实例的CHECK应该是调用的TOBJ.CHECK....
难道真的要在FNewTobj:= Tobj.Create;这里加入
Case Obj Of
1: FNewTobj:= Tobj1.Create;
2: FNewTobj:= Tobj2.Create;
End;
来判断具体子类?
不知道可以不可以加的时候自动判断基类
取的时候 直接类引用就OK了
他自己判断
而不用写Case Obj Of
1: FNewTobj:= Tobj1.Create;
2: FNewTobj:= Tobj2.Create;
End;
但是如果数据太大太多,可能也不好
指针于类引用有多大区别呢.这里是TLIST 返回的是头指针吧. CONST应该只能限制指针地址不被改动
是不是可以使用CONST来限制类引用的修改呢.
不过既然试TLIST的属性,那是不是需要做一个有CONST限制的TLIST类的基类来实现
本来OBJECT有一个CLASSTYPE返回元类的,开始我想是否可以通过NewObj:= Obj.ClassType.Create来实现,不过后来发现不能
难道也不能通过类方法来实现嘛?
其实可以在基类上处理一个返回一个新类引用的类实例方法, (复制构造函数)
用虚方法来代替CASE,在设计每个子类的时候 覆盖就是了...不过..................照理说这样的东东应该是整个类架构基础的部分啊,为什么
VCL没有呢?........................难道是有 或责用什么其他方法实现的....我不知道而已................55
请教各位了.
谢谢.......望回复尽量详细.
------解决方案--------------------
关于这个其实你可以看看TComponent类的设计!
1.
FDataList.Add(Tobj);
也就是说加到FDataList里的实际只是该OTBJ实例的类引用.并不是把值复制给他.
而实际数据是存储在别的地方,比如其他地方A1.
访问这个类的该TLIST属性的时候.我是这么写的
Result:= FDataList;
访问的时候你不一定要返回一个FDataList;你可以增加一个属性数组,
property TObjs[Index: Integer]: TObj read GetTObj;
function TObj.GetTObj(AIndex: Integer): TObj;
begin
if FDataList = nil then TList.Error(@SListIndexError, AIndex);
Result := FDataList[AIndex];
自己写的类,直接从OBJECT继承,
当一个类ListManager有一个TLIST链表属性DataList,用来存储数据的时候的情况.
该类有一个Buy(TObj);的方法来加入一个TOBJ的实例到FDATALIST
不过我是这么写的
FDataList.Add(Tobj);
也就是说加到FDataList里的实际只是该OTBJ实例的类引用.并不是把值复制给他.
而实际数据是存储在别的地方,比如其他地方A1.
访问这个类的该TLIST属性的时候.我是这么写的
Result:= FDataList;
这个实际上是返回的该类的私有成员FDATALIST里存在的TOBJ实例所在地址.
也就是说,编码者在这里通过调用该类的TLIST属性 可以直接修改A1里的对应的实例的数据.
总感觉这样好像不符合封装的基本原理
是不是需要把
FDataList.Add(Tobj);
改为:
FNewTobj:= Tobj.Create;
FNewTobj.Assgin(Tobj); (FNewTobj为该类里的一个TOBJ私有域) //这里加的时候可能是任意TOBJ的基类实例 把加入的类实例复制给一个新的TOBJ的私有类实例
FDataList.Add(Tobj);
这样应该可以创建新的数据,而防止操作ListManager类的时候修改到A1里原来的数据.
不过问题又出来了.因为TOBJ是一个虚拟基类
怎么判断加入的是他的哪个子类呢?
加入以后在读取DataList属性的时候读出来的实例的时候能否(DELPHI是用IS判断符)判断出DATALIST里的引用是哪个TOBJ的基类
的实例,或责都是判断成TOBJ的呢?
比如TOBJ.Check,而TOBJ的子类覆盖了OBJ.check
这个时候因为是使用的NewTobj:= Tobj.Create;所以调用ListManage的DATALIST属性访问到实例的CHECK应该是调用的TOBJ.CHECK....
难道真的要在FNewTobj:= Tobj.Create;这里加入
Case Obj Of
1: FNewTobj:= Tobj1.Create;
2: FNewTobj:= Tobj2.Create;
End;
来判断具体子类?
不知道可以不可以加的时候自动判断基类
取的时候 直接类引用就OK了
他自己判断
而不用写Case Obj Of
1: FNewTobj:= Tobj1.Create;
2: FNewTobj:= Tobj2.Create;
End;
但是如果数据太大太多,可能也不好
指针于类引用有多大区别呢.这里是TLIST 返回的是头指针吧. CONST应该只能限制指针地址不被改动
是不是可以使用CONST来限制类引用的修改呢.
不过既然试TLIST的属性,那是不是需要做一个有CONST限制的TLIST类的基类来实现
本来OBJECT有一个CLASSTYPE返回元类的,开始我想是否可以通过NewObj:= Obj.ClassType.Create来实现,不过后来发现不能
难道也不能通过类方法来实现嘛?
其实可以在基类上处理一个返回一个新类引用的类实例方法, (复制构造函数)
用虚方法来代替CASE,在设计每个子类的时候 覆盖就是了...不过..................照理说这样的东东应该是整个类架构基础的部分啊,为什么
VCL没有呢?........................难道是有 或责用什么其他方法实现的....我不知道而已................55
请教各位了.
谢谢.......望回复尽量详细.
------解决方案--------------------
关于这个其实你可以看看TComponent类的设计!
1.
FDataList.Add(Tobj);
也就是说加到FDataList里的实际只是该OTBJ实例的类引用.并不是把值复制给他.
而实际数据是存储在别的地方,比如其他地方A1.
访问这个类的该TLIST属性的时候.我是这么写的
Result:= FDataList;
访问的时候你不一定要返回一个FDataList;你可以增加一个属性数组,
property TObjs[Index: Integer]: TObj read GetTObj;
function TObj.GetTObj(AIndex: Integer): TObj;
begin
if FDataList = nil then TList.Error(@SListIndexError, AIndex);
Result := FDataList[AIndex];