在进销存中,商品看作一个对象,有商品名称,单价等属性,
仓库里存放着很多的商品,寻仓库跟商品是什么关系?商品也看作一个对象?这个对象里有另一个商品对象?

解决方案 »

  1.   

    type
      TProduct = class
      private
       FName :String;
       FPrice :Float;
        //
      protected
        //
      public
        //
      published
        //
    end;type
        TStore = class
      private
        FProduct :TProduct;  //这里就是仓库拥有商品
        //
      protected
        //
      public
        //
      published
        //
    end;
      

  2.   

    对qybao(阿宝)作答之拾遗:  首先,qybao(阿宝)的作答很基础,其指出了解决该问题的本质方法。其实,在OO中,表示两种类(两个对象)之间的这种关系的概念称为“聚合”,结构表现为“部分-整体”形态,即通常所说的“is a part of”结构。  再者,对qybao(阿宝)所写代码(或称为设计)的补充。可以从两个方面进行合理地完善与扩展。
      一、建议TProduct类为一虚基类(即包含虚方法或动态方法),然后根据不同的商品品种扩展其派生类。其好处对OO有些许了解的朋友应该都知道。
      二、建议TStore类中不要直接拥有每个TProduct对象,而是拥有一个TProduct对象的列表,这样就可以整体上存储所有TProduct对象而在必要时又可以控制其中的每个对象元素了。。
      

  3.   

    根据  creativepeter(头皮屑) 意见整理,不知对否?
    type
      TProduct = class
      private
       FName :String;
       FPrice :Float;
        //
      protected
        //
      public
        procedure a ;virtual;
        procedure b ;virtual;  
        ....                //写一些虚方法,或抽象方法
      published
        //
    end;
    type
      TPorduct1 = class(TProduct )  
      public
        procedure a ;override;        //根据每个类的不同而继承
        
    end;type
      TPorduct2 = class(TProduct )    //根据每个类的不同而继承
      public
        procedure b ;override;
        
    end;type
        TStore = class
      private
        FProduct :^TProduct;  //这里我不太清楚是否这么写?
        //
      protected
        //
      public
        //
      published
        //
    end;
      

  4.   

    我觉得产品和库房虽然是有从属关系,但是不一定用对象包容关系来实现,虽然那样实现
    更加OO,但是麻烦得很,要是你看过来自Borland的面向对象医院信息管理系统你就知道
    要实现一个真正学术高度的OO系统有多么难,理解起来多费劲了,所以尽量避免类设计中嵌套对象.
    以下设计中第一种设计方案用一个整数属性实现了从属关系,第二种方案用函数的参数的方式
    实现了从属关系,如果要真正实现从属关系,那么必须写private FProduct: TProduct了,那样很
    麻烦的,自己看着都头晕.//第一种修改建议:
    type
      TProduct = class
      private
       FName :String;
       FPrice :Float;
       FProductID: integer; //用一个ID代替Product对象
        //
      protected
        //
      public
        property ProductID: integer read FProductID write FProductID;//添加产品ID属性
        //
      //published//Published就面啦,毕竟不是要做组件,对组件作者没用
        //
    end;type
        TStore = class
      private
        FProduct :TProduct;  
        //
      protected
        //
      public
        procedure EnterStort(ProductID: integer);  //这里通过ID调用产品对象,这样比较简单
        procedure ExitStort(ProductID: integer);
        //
      //published//Published就面啦,毕竟不是要做组件,对组件作者没用
        //
    end;//第二种修改建议(有点OO):
    type
      TProduct = class
      private
       FName :String;
       FPrice :Float;
        //
      protected
        //
      public
        //
      //published//Published就面啦,毕竟不是要做组件,对组件作者没用
        //
    end;type
        TStore = class
      private
        FProduct :TProduct;  
        //
      protected
        //
      public
        procedure EnterStort(Product: TProduct);  //这里通过ID调用产品对象,这样比较简单
        procedure ExitStort(Product: TProduct);
        //
      //published//Published就面啦,毕竟不是要做组件,对组件作者没用
        //
    end;
    ....
    implementationTStore.EnterStort(Product: TProduct);
    begin
      if Product.FName = '香皂' and Product.FPrice < 2 then
      begin
        Product.Buy();
      end;
    end;TStore.ExitStort(Product: TProduct);
    begin
      if Product.FPrice > 5 then
      begin
        Product.MakeMoney();  //发财啦!:)
      end;  
    end;
      

  5.   

    TProduct = class(TCollectItem)
    ...
    end;
    TProducts = class(TCollect)
    ...
    end;
    TStock = class
    private
      FProducts: TProducts;
    end;
      

  6.   

    要是你看过来自Borland的面向对象医院信息管理系统
    // TO:  man8888(北京男人) ( ) 
    哪裡可以看到呢 哥們。
      

  7.   

    对xjwy(程序春秋)作答之拾遗:
      一、代码中不妥的部分:
      ①不知为何需要那么多的type关键字,只要在所有声明的类型的前面写一个type即可;
      ②
      TStore = class
      private
        FProduct : ^TProduct;  //这里我不太清楚是否这么写?
        //
      protected
        //
      public
        //
      published
        //
      end;
      这个FProduct : ^TProduct的声明不符我的作法,其实与本题提问者的写法相同。
      ③
      TPorduct1 = class(TProduct)  
      public
        procedure a ;override;        //根据每个类的不同而继承
        ...
      end;
      procedure a ;override;  
    {根据每个类的不同而继承←这个注解有问题,派生类不管有多少不同,只要继承同一基类,将继承其中所有数据成员、属性和方法成员等等,其自身没有选择余地,该注解应改为“根据每个类的不同而覆盖”。}
      ④
      一个容易被大家忽略的问题,就是Delphi里面没有float数据类型。
      ⑤
      TPorduct1、TPorduct2猜测不错的话是笔误吧,应该是TProduct1、TProduct2。
      二、建议作法:
      以下是我对该问题的一个解决方案(Delphi7 + Windows2000 Server测试通过),当然作为一个原型,有很多地方还值得雕琢。
      建立一个新工程,保存主界面窗体及其单元文件,源代码如下:
    unit untMain;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, untBusiness;//untBusiness是接下来需要手动添加的一个单元文件type
      TMainForm = class(TForm)
        btnGenProduct: TButton;
        btnGenStore: TButton;
        procedure btnGenProductClick(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
        procedure btnGenStoreClick(Sender: TObject);
      private
        FStore : TStore;
      public
        { Public declarations }
      end;var
      MainForm: TMainForm;implementationconst
      ObjectInfo = 'Price of this Prodcut named %s is %8.2f';{$R *.dfm}procedure TMainForm.btnGenProductClick(Sender: TObject);
    var
      aProduct : TProduct;
    begin
      aProduct := TProduct1.Create;
      try
        aProduct.Name := 'AProduct1Obj';
        aProduct.Price := 1.2;
        ShowMessage(Format(ObjectInfo, [aProduct.Name, aProduct.Price]));
        aProduct.a;
        aProduct.b;
      finally
        aProduct.Free;
      end;
      aProduct := TProduct2.Create;
      try
        aProduct.Name := 'AProduct2Obj';
        aProduct.Price := 199.98;
        ShowMessage(Format(ObjectInfo, [aProduct.Name, aProduct.Price]));
        aProduct.a;
        aProduct.b;
      finally
        aProduct.Free;
      end;
    end;procedure TMainForm.FormCreate(Sender: TObject);
    begin
      FStore := TStore.Create;
    end;procedure TMainForm.FormDestroy(Sender: TObject);
    begin
      FStore.Free;
    end;procedure TMainForm.btnGenStoreClick(Sender: TObject);
    var
      aProduct : TProduct;
    begin
      aProduct := TProduct1.Create;
      aProduct.Name := 'AProduct1Obj';
      aProduct.Price := 1.2;
      FStore.AddProduct(aProduct);
    end;end.  接下来,手动添加一个单元文件,源代码如下:
    unit untBusiness;interfaceuses
      SysUtils, Dialogs, Contnrs;type
      TProduct = class
      private
       FName : string;
       FPrice : Double;  //将FPrice设为Double类型
       function GetName : string;
       function GetPrice : Double;
       procedure SetName(Value : string);
       procedure SetPrice(Value : Double);
      public
        property Name : string read GetName write SetName;
        property Price : Double read GetPrice write SetPrice;
        constructor Create;
        procedure a;virtual;
        procedure b;virtual;
      end;
      TProduct1 = class(TProduct)
      public
        procedure a;override;        //根据每个类的不同而覆盖
      end;
      TProduct2 = class(TProduct)    //根据每个类的不同而覆盖
      public
        procedure b;override;
      end;
      TStore = class
      private
        FProductList : TObjectList;  //使用TObjectList对象保存或移除仓库中的商品对象
        function GetProductList: TObjectList;
      public
        constructor Create;
        destructor Destroy;override;
        property ProductList : TObjectList read GetProductList;
        procedure AddProduct(aProduct : TProduct);
      end;
      
    const
      MessageText = 'This is a method called %s';implementation{ TProduct }procedure TProduct.a;
    begin
      ShowMessage(Format(MessageText, ['TProduct.a']));
    end;procedure TProduct.b;
    begin
      ShowMessage(Format(MessageText, ['TProduct.b']));
    end;constructor TProduct.Create;
    begin
      FName := 'AProduct';
      FPrice := 0;
      ShowMessage(Format(MessageText, ['TProduct.Create']));
    end;function TProduct.GetName: string;
    begin
      Result := FName;
    end;function TProduct.GetPrice: Double;
    begin
      Result := FPrice;
    end;procedure TProduct.SetName(Value: string);
    begin
      if Value <> FName then
        FName := Value;
    end;procedure TProduct.SetPrice(Value: Double);
    begin
      if Value <> FPrice then
        FPrice := Value;
    end;{ TProduct1 }procedure TProduct1.a;
    begin
      inherited;
      ShowMessage(Format(MessageText, ['TProduct1.a']));
    end;{ TPorduct2 }procedure TProduct2.b;
    begin
      inherited;
      ShowMessage(Format(MessageText, ['TProduct1.b']));
    end;{ TStore }procedure TStore.AddProduct(aProduct: TProduct);
    begin
      FProductList.Add(aProduct);
      ShowMessage('A Product has been added!');
    end;constructor TStore.Create;
    begin
      FProductList := TObjectList.Create;
      FProductList.OwnsObjects := True;  //使FProductList在销毁时自动销毁其下拥有的对象
    end;destructor TStore.Destroy;
    begin
      FProductList.Free;
      inherited;
    end;function TStore.GetProductList: TObjectList;
    begin
      Result := FProductList;
    end;end.
      有些比较重要的地方我做了注解,其余部分请自行研究,不妥之处请指正。
      

  8.   

    强烈感谢
    回复人: creativepeter(头皮屑) ( ) 信誉:100  2005-02-22 16:24:00  得分: 0  
    干到2:00
    写出来了,测试通过。
    哪有空间我贴个MM的图。
      

  9.   

    贴MM的图做甚?
    还请qufo (1)(飞)(如果后面没有出现<%Script,则表示入侵成功) 兄早日结帖,以免夜长梦多:-)。
      

  10.   

    MM-Model Maker
    贴MM图看得比较清楚嘛。
      

  11.   

    MM图放在
    http://blog.csdn.net/qufo/archive/2005/02/26/302591.aspx
    自己看。