如何制作这个OO?

时间:2010-04-09 15:19:45

标签: delphi oop delphi-2009

抱歉标题不好,我是OOP的新手,所以我不知道我需要做什么。

我有10个不同的继承一个Object的对象。它们有不同数量和类型的类成员,但它们都有一个共同的属性 - 可见。

type TSObject=class(TObject);
  protected
    Visible:boolean;
  end;

type
  TObj1=class(TSObject)
  private 
    a:integer;
    ...(More members)
end;
  TObj2=class(TSObject)
  private 
    b:String;
    ...(More members)
end;

...(Other 8 objects)

对于他们每个我都有一个变量。

var Obj1:TObj1;
    Obj2:TObj2;
    Obj3:TObj3;
    ....(Other 7 objects)

规则1:一次只能初始化一个对象(其他人必须被释放)才能看到。

对于这条规则,我有一个全局变量

var CurrentVisibleObj:TSObject; //Because they all inherit TSObject

最后,有一个程序会改变可见性。

procedure ChangeObjVisibility(newObj:TSObject);
begin
  CurrentVisibleObj.Free; //Free the old object
  CurrentVisibleObj:=newObj; //assign the new object
  CurrentVisibleObj:= ??? //Create new object
  CurrentVisibleObj.Visible:=true; //Set visibility to new object
end;

有我的问题,我不知道如何初始化它,因为派生类是未知的(TObj1,TObj2,Tobj3 ......哪一个?)。

我该怎么做?

我简化了解释,在项目中有TFrame,每个都有不同的控件,我必须以相同的方式设置可见/不可见(通过只保留一个帧初始化)。

对于标题再次抱歉,我非常新的OOP。

5 个答案:

答案 0 :(得分:1)

如果这是关于一组TFrame控件,并且您希望一次只能看到其中一个,则无需一直释放和创建它们。您可以将每个帧放在TPageControl的一个页面上,然后隐藏选项卡条并使用TPageControl的ActivePage属性更改可见帧。

答案 1 :(得分:1)

  

有我的问题,我不知道怎么回事   初始化它,因为派生   上课是   未知(TObj1,TOBJ2,Tobj3 ...这   一个?)。

嗯,基本上有两种选择:

  • 要么将要创建的对象的类型作为参数传递给方法,例如调用者必须告诉你它想要创建什么

  • 您可以根据其他信息确定要创建的类型;一种简单的方法是创建一个与您最初传入的对象类型相同的对象(不知道在您的上下文中是否有意义)

我已经有一段时间了,因为我已经完成了任何严肃的Delphi工作,但我想我依旧记得在Delphi中有一种表达你想要的“类型”的方法。或者你甚至可以根据类型的名称创建给定类型的实例作为字符串(例如,基于传入的字符串“TObj2”创建TObj2的实例)

答案 2 :(得分:1)

这里的第一个问题之一是您似乎假设您可以将未初始化的变量传递给ChangeObjVisibility。

ChangeObjVisibility(Obj3);

这里,如果Obj3为零(或者更糟,是悬空指针),ChangeObjVisibility无法知道它需要创建的对象的类型。

你可以通过一个const数组或一个带case的函数来获得创建帧的方法之一。

type
  TSObjectClass = class of TSObject;
const
  ObjectClasses = array[0..X] of TSObjectClass = (TObj1, TObj2, TObj3, ...)

function GetFrameclass(Index : Integer) : TSObjectClass;
begin
  Result := ObjectClasses[Index]

  OR 

  case Index of
    0 : Result := TObj1;
    1 : Result := TObj2;
    (...)
  end;
end;

如果框架不需要任何特殊的初始化,那将会有效。

接下来,您可以拨打这样的电话:

procedure ChangeCurrentFrame(NewFrameIndex : Integer);
var FrameClass : TSObjectclass;
    vFrame : TSObject;
begin
  FrameClass := GetFrameClass(NewFrameIndex);
  if CurrentVisibleObj.ClassType <> FrameClass then
  begin
    vFrame := FrameClass.Create(nil);
    SetCurrentFrame(vFrame);
  end;
end;

procedure SetCurrentFrame(newObj:TSObject); 
begin 
  if Assigned(CurrentVisibleObj) then
    CurrentVisibleObj.Free; //Free the old object 
  CurrentVisibleObj:=newObj; //assign the new object 
  if Assigned(CurrentVisibleObj) then
    CurrentVisibleObj.Visible:=true; //Set visibility to new object 
end; 

在这里,SetCurrentFrame取代你ChangeObjVisibility(这里你真正做的是改变当前帧,改变可见性只是一个“副作用”)

答案 3 :(得分:0)

由于is-a关系,您甚至可以在派生对象上访问基本属性。在您的情况下,您希望在多个对象之间具有共享状态,考虑这一点的一种方法是创建将保存对象的管理器类。它只会选择一个对象作为可见对象。您可能不需要包含对象的visible属性,但此设计也允许这样做。

容器

列出MyObjects; 对象MyVisibleObject;

答案 4 :(得分:0)

每次想要更改其可见性时,都不应该创建和释放框架 - 它们应始终始终初始化。