封装有关问题 以及 复制子类 有关问题 思考良久.

封装问题 以及 复制子类 问题 思考良久.....
自己写的类,直接从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];