自己写的类,直接从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请教各位了.
谢谢.......望回复尽量详细.

解决方案 »

  1.   

    关于这个其实你可以看看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];
    end;因为属性是只读的,而你的FDataList是Private的,所以就没办法修改到FDataList里面的东西了.2.
    FDataList.Add(Tobj); 
     改为:
        FNewTobj:= Tobj.Create;
        FNewTobj.Assgin(Tobj); (FNewTobj为该类里的一个TOBJ私有域)      //这里加的时候可能是任意至于这里,我想,你是想知道如果正确的创建子类的实例,可以这样子:
    procedure Buy(aObj: TObj);
    var
      NewObj: TObj;
    begin
      NewObj := aObj.ClassType.Create;   //返回对象变量的正确类型,也就是你的子类,再CREATE
      NewObj.Assgin(aObj);
      FDataList.Add(NewObj);
    end;
      

  2.   

    你好
    谢谢你的回复。
    就是对VCL源码还没学习过,所以闹除这样的笑话真是不好意思。
    第一个问题我大概清楚了。太缺乏经验了,呵呵 主要是太习惯用TLIST了至于第2个问题。
    你说的使用
    NewObj := aObj.ClassType.Create;   //返回对象变量的正确类型,也就是你的子类,再CREATE其实在我提问之前我就想到过的,查了一下TOBJECT 发现她返回的是一个原类 TCLASS
    实际自己试了一下发现却不能编译通过。
    是这么试的。
    打开DELPHI ,随便新见一个项目,她自动会生成一个文件嘛
    type
      TForm1 = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.DFM}procedure TForm1.Button1Click(Sender: TObject);
    var
      Test:Tform1;
    begin
      Test:= form1.classtype.create;   //这里编译的时候直接就出错了
                                       //说的不能吧TOBJECT 赋值给TFORM。
    end; 我试过把TEST声明成TONJECT就可以通过。
    不过按照字面理解: ClassType.Create;   //返回对象变量的正确类型
    她却返回的试TOBJECT。。不解了还请大哥点明诀窍到底试该怎么样才能正确的创建子类的实例
      

  3.   

    Test:= TForm1(form1.classtype.create);    //需要做一下类型转换!
      

  4.   

    恩 谢谢chenzhuo(睡到自然醒) 
    我也自己测试过了
    他用的元类来处理的。实际上创建的时候已经是实际的需要的类实例了