Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 10.09.2010, 12:22   #1
Roof
Форумчанин
 
Аватар для Roof
 
Регистрация: 01.02.2007
Сообщений: 785
По умолчанию получить значение поля другого класса

Вот мой модуль с несколькими классами.
Код:
unit Land;

interface
uses Classes;

type

  TSeedGrowing = class(TPersistent)
  private
    FNormSowing: real;
    ...

  public
    procedure CalcNormSowing;    //интересует эта процедура
    ...
  published
    property NormSowing: real read FNormSowing;
    ...
  end;

  TLand = class(TCollectionItem)
  private
    FArea: real;
    FProductivity: real;
    FCost: real;
    FPrice: real;
    FSeedGrowing: TSeedGrowing;

  public
    constructor Create(Collection: TCollection); override;
    destructor Destroy; override;

  published
    property Area: real read FArea write FArea;
    property Productivity: real read FProductivity write FProductivity;
    property Cost: real read FCost;
    property Price: real read FPrice write FPrice;
    property SeedGrowing: TSeedGrowing read FSeedGrowing write FSeedGrowing;

  end;

  TCollLand = class(TCollection)
  public
    function GetLand(index: Integer): TLand;
    procedure SetLand(index: Integer; Value: TLand);
    function Add: TLand;
    property Items[index: Integer]: TLand read GetLand
    write SetLand; default;

  end;
  TAcLand = class(TComponent)
  private
    name: string;
    FCollLand: TCollLand;

  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;

  published
    property CollLand: TCollLand read FCollLand write FCollLand;

  end;

implementation

{ TLand }

constructor TLand.Create(Collection: TCollection);
begin
  inherited;
  FSeedGrowing := TSeedGrowing.Create;

end;

destructor TLand.Destroy;
begin
  FSeedGrowing.Free;
  inherited;
end;

{ TSeedGrowing }

procedure TSeedGrowing.CalcNormSowing;
begin
  //FNormSowing := ;
end;

{ TCollLand }

function TCollLand.Add: TLand;
begin
  Result := TLand(inherited Add);
end;

function TCollLand.GetLand(index: Integer): TLand;
begin
  Result := TLand(inherited Items[index]);
end;

procedure TCollLand.SetLand(index: Integer; Value: TLand);
begin
  Items[index].Assign(Value);
end;

{ TAcLand }

constructor TAcLand.Create(AOwner: TComponent);
begin
  inherited;
  FCollLand := TCollLand.Create(TLand);
end;

destructor TAcLand.Destroy;
begin
  FCollLand.Free;
  inherited;
end;

end.
Меня интересует реализация процедуры CalcNormSowing в классе TSeedGrowing. Например, значение поля FNormSowing в этой процедуре считается как произведение значения поля FArea (класс TLand) и значения поля FProductivity (класс TLand) и произведение некоторых полей класса TSeedGrowing.
Ничего лучшего, кроме как передать эти значения в виде параметров процедуры я не придумал. Вот так:
procedure CalcNormSowing(Area, Productivity: real);
Возможно ли обойтись без параметров? Как-то сослаться на значения этих полей (FArea, FProductivity) в самой процедуре?
Изо всей благодати
В руках крепко сжатых
Я донесу только капли
Roof вне форума Ответить с цитированием
Старый 10.09.2010, 12:38   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Ну а чем параметры то не угодили?
В крайнем случае можно вытянуть эти поля в отдельный класс (оъект - хранилище), а во всех остальных его использовать
Код:
type
 basa=class
  q,w,e:integer;
 end;

 o1=class
  bs:basa;
  procedure b;
 end;
 o2=class
  bs:basa;
  procedure b;
 end;

 var b:basa;
  q:o1;
  w:o2;
{ o1 }

procedure o1.b;
begin
 bs.e:=bs.q+bs.w;
end;

{ o2 }

procedure o2.b;
begin
  bs.e:=bs.q-bs.w;
end;

begin
 b:=basa.Create; b.q:=1;b.w:=2;
 q:=o1.Create;  q.bs:=b; q.b;
 w:=o2.Create;  w.bs:=b; w.b;
  { TODO -oUser -cConsole Main : Insert code here }
end.
Код наспех, но смысл в том чтоб создать отдельный объект для использования во всех других объектах.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 10.09.2010, 12:51   #3
Roof
Форумчанин
 
Аватар для Roof
 
Регистрация: 01.02.2007
Сообщений: 785
По умолчанию

Параметры угодили но меня не покидала мысль - что можно сделать проще/по-другому.
Смысл я понял, спасибо. В моем случае с параметрами проще реализовать, на мой взгляд.
Изо всей благодати
В руках крепко сжатых
Я донесу только капли
Roof вне форума Ответить с цитированием
Старый 10.09.2010, 13:02   #4
mutabor
Телепат с дипломом
Старожил
 
Аватар для mutabor
 
Регистрация: 10.06.2007
Сообщений: 4,929
По умолчанию

Можно еще сделать привязку к тем другим объектам, в к-рых нужные свойства. Так удобно делать, если объекты взаимосвязаны и работают в комплексе, в одной системе, неразлучно друг от друга, но при этом они разные объекты. Тогда делаешь public поля:
Land: TLand;
Traktor: TTraktor;
// и т.д.
На момет создания объекта они будут ссылаться в nil. Но после создания ты можешь им присвоить ссылки (должны быть уже созданы):
Object.Land := Land1;
Object.Traktor := Belarus;
И потом внутри класса можешь использовать их не получая ничего в параметрах.

И еще, разновидность этого способа: если нужно получить целую кучу параметров, но из одного объекта, передавай просто ссылку на объект и вытягивай из него, что нужно.
Код:
procedure SomeProc(Obj: TSomeObject);
  with Obj do begin
    // и тут доставай из него что тебе нужно
  end;
The future is not a tablet with a 9" screen no more than the future was a 9" black & white screen in a box. It’s the paradigm that survives. (Kroc Camen)
Проверь себя! Онлайн тестирование | Мой блог

Последний раз редактировалось mutabor; 10.09.2010 в 13:18.
mutabor вне форума Ответить с цитированием
Старый 10.09.2010, 13:24   #5
Roof
Форумчанин
 
Аватар для Roof
 
Регистрация: 01.02.2007
Сообщений: 785
По умолчанию

2 mutabor - второй способ понял, но, думаю, использовать такое только если действительно надо получить кучу параметров. Хотя я стараюсь разбивать на отдельные процедуры, чтобы избежать как раз таки кучи параметров.

А вот
Цитата:
Тогда делаешь public поля
- где создавать?
Цитата:
И потом внутри класса можешь использовать их не получая ничего в параметрах.
- и это не понял. Т.е. в моем случае можно записать так:

Код:
procedure TSeedGrowing.CalcNormSowing;
begin
  FNormSowing := FArea * FProductivity;
end;
??
Изо всей благодати
В руках крепко сжатых
Я донесу только капли

Последний раз редактировалось Roof; 10.09.2010 в 13:31.
Roof вне форума Ответить с цитированием
Старый 10.09.2010, 13:44   #6
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
Т.е. в моем случае можно записать так:
Только если FArea и FProductivity будут полями этого класса.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 10.09.2010, 13:46   #7
Roof
Форумчанин
 
Аватар для Roof
 
Регистрация: 01.02.2007
Сообщений: 785
По умолчанию

2 Stilet - это понятно. Но они поля другого класса. Я не понял вот этого:
Цитата:
Тогда делаешь public поля
и
Цитата:
И потом внутри класса можешь использовать их не получая ничего в параметрах.
и потому привел этот пример.
Изо всей благодати
В руках крепко сжатых
Я донесу только капли
Roof вне форума Ответить с цитированием
Старый 10.09.2010, 13:55   #8
mutabor
Телепат с дипломом
Старожил
 
Аватар для mutabor
 
Регистрация: 10.06.2007
Сообщений: 4,929
По умолчанию

Посмотрел внимательней код, можно сделать еще лучше. У тебя ведь он (FSeedGrowing) внутри TLand, тогда в конструктор ему передавай ссылку на хозяина.

Создание тогда у тебя будет иметь вид:
FSeedGrowing := TSeedGrowing.Create(Self);

Объявление конструктора такое:
constructor Create(AOwner: TLand);

Доступ к полям, внутри TSeedGrowing:
Owner.FArea

Поля эти в TLand вынеси в паблик, иначе не будет доступа к ним.
The future is not a tablet with a 9" screen no more than the future was a 9" black & white screen in a box. It’s the paradigm that survives. (Kroc Camen)
Проверь себя! Онлайн тестирование | Мой блог
mutabor вне форума Ответить с цитированием
Старый 10.09.2010, 14:38   #9
Roof
Форумчанин
 
Аватар для Roof
 
Регистрация: 01.02.2007
Сообщений: 785
По умолчанию

2 mutabor - пробовал, пробовал, так и не получилось обратиться к полям, внутри TSeedGrowing через Owner
В реализации процедуры TSeedGrowing.CalcNormSowing; в строке
Код:
  FNormSowing := Owner.FArea * Owner.FProductivity;
Пишет, что не знает кто такой Owner. Вот весь код с исправлениями:
Код:
unit Land;

interface
uses Classes;

type

  TLand = class;

  TSeedGrowing = class(TPersistent)
  private
    FNormSowing: real;

  public
    constructor Create(AOwner: TLand);
    destructor Destroy;
    procedure CalcNormSowing; //интересует эта процедура

  published
    property NormSowing: real read FNormSowing;

  end;

  TLand = class(TCollectionItem)
  private
    FCost: real;
    FPrice: real;

  public
    FSeedGrowing: TSeedGrowing;
    FArea: real;
    FProductivity: real;
    constructor Create(Collection: TCollection); override;
    destructor Destroy; override;

  published
    property Area: real read FArea write FArea;
    property Productivity: real read FProductivity write FProductivity;
    property Cost: real read FCost;
    property Price: real read FPrice write FPrice;
    property SeedGrowing: TSeedGrowing read FSeedGrowing write FSeedGrowing;

  end;

  TCollLand = class(TCollection)
  public
    function GetLand(index: Integer): TLand;
    procedure SetLand(index: Integer; Value: TLand);
    function Add: TLand;
    property Items[index: Integer]: TLand read GetLand
    write SetLand; default;

  end;
  TAcLand = class(TComponent)
  private
    name: string;
    FCollLand: TCollLand;

  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;

  published
    property CollLand: TCollLand read FCollLand write FCollLand;

  end;

implementation

{ TLand }

constructor TLand.Create(Collection: TCollection);
begin
  inherited;
  FSeedGrowing := TSeedGrowing.Create(Self);

end;

destructor TLand.Destroy;
begin
  FSeedGrowing.Free;
  inherited;
end;

{ TSeedGrowing }

procedure TSeedGrowing.CalcNormSowing;
begin
  FNormSowing := Owner.FArea * Owner.FProductivity;
end;

constructor TSeedGrowing.Create(AOwner: TLand);
begin

end;

destructor TSeedGrowing.Destroy;
begin

end;

{ TCollLand }

function TCollLand.Add: TLand;
begin
  Result := TLand(inherited Add);
end;

function TCollLand.GetLand(index: Integer): TLand;
begin
  Result := TLand(inherited Items[index]);
end;

procedure TCollLand.SetLand(index: Integer; Value: TLand);
begin
  Items[index].Assign(Value);
end;

{ TAcLand }

constructor TAcLand.Create(AOwner: TComponent);
begin
  inherited;
  FCollLand := TCollLand.Create(TLand);
end;

destructor TAcLand.Destroy;
begin
  FCollLand.Free;
  inherited;
end;

end.
Для проверки могу выложить весь этот тестовый проект сюда в архиве.
Изо всей благодати
В руках крепко сжатых
Я донесу только капли

Последний раз редактировалось Roof; 10.09.2010 в 14:41.
Roof вне форума Ответить с цитированием
Старый 10.09.2010, 14:44   #10
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Имелось ввиду это:
Код:
  TSeedGrowing = class(TPersistent)
  private
    FNormSowing: real;
    Owner: TLand;
  public
    constructor Create(AOwner: TLand);
    destructor Destroy;
    procedure CalcNormSowing; //интересует эта процедура
...
procedure TSeedGrowing.CalcNormSowing;
begin
  FNormSowing := Owner.FArea * Owner.FProductivity;
end;

constructor TSeedGrowing.Create(AOwner: TLand);
begin
 Owner:=AOwner;
end;
и в этом случае:
Код:
TLand = class
 FArea,FProductivity:integer;
end;
Обязательно.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как вызвать метод из другого класса в C# KobolD Помощь студентам 6 25.06.2010 14:12
получить данные поля исходя из lookup-поля malayka Помощь студентам 0 21.04.2010 21:19
как получить значение поля грид на основе значения другого lookUp поля malayka БД в Delphi 0 21.04.2010 19:06
Подписаться на событие другого класса boris-blade Общие вопросы .NET 1 06.04.2010 22:53
Если в классе объявить объект другого класса,будет ли видно переменные первого класса из объекта второго? TwiX Общие вопросы Delphi 3 15.11.2009 00:54