Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2005.03.27;
Скачать: [xml.tar.bz2];

Вниз

Класс и Объект   Найти похожие ветки 

 
capkoh   (2005-03-13 21:47) [0]

Объясните ламеру, чем отличается класс от объекта в Delphi (У меня 7). Имеется в виду следующее: есть такие объявления:

type
   TSomeClass = class (...) end;
   TSomeObject = object (...) end;

var
  SomeClass: TSomeClass;
  SomeObject: TSomeObject;

При этом в SomeClass уже имеются какие-то методы (ClassName, Dispatch...), а в SomeObject нет. Я так полагаю, что class"ы нужны для создания визуальных компонентов, в object"ы для структур данных. Так вот, в чем же Существенная между ними разница?


 
Sergey_Masloff   (2005-03-13 21:55) [1]

Прочел бы ты справку для начала. Потом про существенную поговорим.


 
jack128 ©   (2005-03-13 22:02) [2]

object - устаревшая конструкция. Обозначает примерно тоже, что и class за определенными искючениями и ограничениями(в часности object"ы не имееют единого предка, в отличее от class"ов, переменные данного типа не являются указателями, и тд и тп)


 
begin...end ©   (2005-03-13 22:07) [3]

> capkoh   (13.03.05 21:47)

> Я так полагаю, что class"ы нужны для создания
> визуальных компонентов, в object"ы для структур данных.

Object"ы могут использоваться не только как структуры данных. Они так же, как и классы, могут содержать поля, свойства и методы. Правда, все эти составляющие не могут быть объявлены в разделе published. У object"ов нет конструкторов и деструкторов. Можно объявлять переменную нужного объектного типа и сразу с ней работать, или объявлять переменную-указатель на объектный тип, и выделять для неё память динамически с помощью процедур New и Dispose.

Вот пример описания object"а:

interface
 
 type
   TMyObject = object
   public
     ObjField: String;
     procedure ShowObjField;
     property ObjProperty: String read ObjField write ObjField;
   end;

...

implementation

procedure TMyObject.ShowObjField;
begin
 ShowMessage(ObjField)
end


А работать с ним можно так:

var
 MyObject: ^TMyObject;
begin
 New(MyObject);
 MyObject.ObjProperty := "text";
 MyObject.ShowObjField;
 Dispose(MyObject)
end


или так:

var
 MyObject: TMyObject;
begin
 MyObject.ObjProperty := "text";
 MyObject.ShowObjField;
end


Object"ы оставлены для совместимости с Borland Pascal"ем.

См. в справке: object types.


 
palva ©   (2005-03-13 22:54) [4]

По-моему, у объектов могут быть конструкторы, только их принято называть не Create а Init. Как давно это было...


 
default ©   (2005-03-13 23:09) [5]

palva ©   (13.03.05 22:54) [4]
да, могут, насколько я помню это нужно для объектов в которых используются динамически методы(dynamic, virtual)
в них иниц-ия нужная происходит для обеспечения работы механизма позднего связывания
вообщем всё это старо и автора сабжа лучше в голову это не брать


 
Defunct ©   (2005-03-14 05:15) [6]

> класс от объекта

В отличие от класса, объект не нужно создавать, его достаточно объявить как переменную и сразу можно с ним работать.

1). Объявляем TRecord как Object:

TRecord = Object
 FirstName : String;
 LastName  : String;
 id        : Integer;

 function GetFullInfo:String;
end;
..
..

function TRecord.GetFullInfo;
begin
 Result := FirstName + " " + LastName + " (" +IntToStr(Age)+")";
end;
..
..
..
var
  Person : TRecord; // Память уже выделена под все поля TRecord
begin
 Person.FirstName := "lalala";
 Person.LastName := "blablabla";
 Person.id := 34;
 ShowMessage( Person.GetFullInfo );
end;


2). если объявить TRecord как класс, тогда..:

TRecord = class
 FirstName : String;
 LastName  : String;
 id        : Integer;

 function GetFullInfo:String;
end;
..
..

function TRecord.GetFullInfo;
begin
 Result := FirstName + " " + LastName + " (" +IntToStr(Age)+")";
end;
..
..
var
  Person : TRecord; // Person это указатель
begin
  Person := TPerson.Create; // Создать экземпляр (выделить память)
  try
     Person.FirstName := "lalala";
     Person.LastName := "blablabla";
     Person.id := 34;
     ShowMessage( Person.GetFullInfo );
  finally
     Person.Free  // Освободить выделенную память
  end
end;


Короче говоря, все еще есть область применения для Object. Хотя бы там где требуется просто сгруппировать множество локальных полей данных и методов работы с ними, и не заботиться об освобождении памяти: это значит, что если Object будет объявлен как локальная переменная какой-то функции, то память занимаемая им освободится на выходе из функции автоматически. Если же забыть разрушить экземпляр класса, то он так и останется висеть в памяти.

PS: если где ошибся, поправьте.


 
Defunct ©   (2005-03-14 05:23) [7]

begin...end ©   (13.03.05 22:07) [3]

Ерунду наговорили:

> У object"ов нет конструкторов и деструкторов.

неправда.
виртуальные методы были еще в TP6, а соответственно и конструкторы и деструкторы в объектах есть.


> А работать с ним можно так:
> var
>  MyObject: ^TMyObject;

Зачем с ним работать так? Если надо работать "так" так и создавать надо класс.


> или так:
> var
>   MyObject: TMyObject;

Только так, или вообще никак.


 
begin...end ©   (2005-03-14 09:51) [8]

> Defunct ©   (14.03.05 5:23) [7]

>> У object"ов нет конструкторов и деструкторов.
> неправда.
> виртуальные методы были еще в TP6, а соответственно и
> конструкторы и деструкторы в объектах есть.

Я имел в виду встроенные конструкторы и деструкторы. Их в object"ах действительно нет. Потому что у object"ов нет общего предка, в отличие от классов (для последних общим предком является TObject, в котором конструктор и деструктор уже есть). Ну а если Вы даже в этом сомневаетесь, - обратитесь к справке, она будет рада.

Разумеется, объявить конструктор можно и в object"е. Только в Delphi это объявление не нужно, понимаете? Да, в Турбо Паскале у объекта с виртуальными методами должен был быть конструктор/деструктор, и конструктор должен был вызываться, иначе ТВМ не была бы правильно настроена, и объект не работал бы. Вот пример из Паскаля:

program Objects;

type

 TFirstObject = object
   constructor Init;
   procedure MyProc; virtual;
 end;

 TSecondObject = object(TFirstObject)
   constructor Init;
   procedure MyProc; virtual;
 end;

 constructor TFirstObject.Init;
 begin
 end;

 constructor TSecondObject.Init;
 begin
 end;

 procedure TFirstObject.MyProc;
 begin
   WriteLn("1")
 end;

 procedure TSecondObject.MyProc;
 begin
   WriteLn("2")
 end;

var
 FObj: TFirstObject;
 SObj: TSecondObject;
begin
 FObj.Init;
 SObj.Init;

 FObj.MyProc;
 SObj.MyProc;
 ReadLn
end.


Заметьте - без вызовов конструкторов (выделенные строки) ничего нормально не работало бы.

А теперь вот аналогичный пример в Delphi:

program Objects;

{$APPTYPE CONSOLE}

uses
 SysUtils;

type

 TFirstObject = object
   procedure MyProc; virtual;
 end;

 TSecondObject = object(TFirstObject)
   procedure MyProc; virtual;
 end;

 procedure TFirstObject.MyProc;
 begin
   WriteLn("1")
 end;

 procedure TSecondObject.MyProc;
 begin
   WriteLn("2")
 end;

var
 FObj: TFirstObject;
 SObj: TSecondObject;
begin
 FObj.MyProc;
 SObj.MyProc;
 ReadLn
end.


И снова заметьте - никаких конструкторов нет и в помине, и, тем не менее, всё прекрасно работает. В отличие от Турбо Паскаля.

>>  MyObject: ^TMyObject;
> Зачем с ним работать так? Если надо работать "так" так
> и создавать надо класс.

Defunct, если Вам нужно динамически разместить в памяти какую-нибудь переменную - например, запись очень большого размера - Вы тоже, вместо того, чтобы использовать процедуры по выделению/освобождению памяти (New/Dispose или GetMem/FreeMem), превращаете record в class? Ну, в таком случае, мне Вас искренне жаль.

Причём я не говорил, что для object"ов нужно выделять память динамически. Я говорил, что это можно сделать. И так часто делали в том же Турбо Паскале. Более того: я даже не говорил, что с object"ами вообще нужно работать, и подчеркнул, что они оставлены только для обратной совместимости. А если object"ы переделывать в class"ы (как это предложили Вы) только потому, что память под них выделялась динамически - тогда нафиг вообще эта обратная совместимость нужна?


 
Defunct ©   (2005-03-14 11:01) [9]

begin...end ©   (14.03.05 09:51) [8]

> никаких конструкторов нет и в помине

то что вы их не объявили, не означает невозможность написания слова constructor. Ведь фраза "в типе record нет методов", трактуется однозначно. Разницу чуете?

> Defunct, если Вам нужно динамически разместить в памяти какую-нибудь переменную - например, запись очень большого размера - Вы тоже, вместо того, чтобы использовать процедуры по выделению/освобождению памяти (New/Dispose или GetMem/FreeMem), превращаете record в class?

Зависит от задачи, наиболее вероятно, что для размещения в памяти чего либо большого я воспользуюсь TMemoryStream.

> Ну, в таком случае, мне Вас искренне жаль.

Программа с обилием New/Dispose/GetMem/FreeMem разных каракулей типа шляпок и собачек на народном языке называется - глюкодром. Так что жалейте лучше себя.

> Причём я не говорил, что для object"ов нужно выделять память динамически. Я говорил, что это можно сделать. И так часто делали в том же Турбо Паскале.

Да, и именно это Ваше изречение поможет понять разницу между классом и объектом. Память можно выделить динамически под переменную любого типа, но не всегда это нужно. Общепринятую переменную i: integer предпочитают объявлять локально и не заботиться о выделении и освобождении памяти для нее. Точно также может возникнуть необходимость объединения небольшого кол-ва полей и методов работы с ними и не заботиться о выделении памяти под них (вот тут object и будет лучшим решением).


> А если object"ы переделывать в class"ы (как это предложили Вы) только потому, что память под них выделялась динамически -

Не переделывать, а сразу осознавая задачу и зная возможности использовать то, что больше всего подходит. Вы как раз лишаете, создавшего эту ветку, узнать возможности delphi.

Даете пример со шляпками New/Dispose, зачем оно надо? Если бы вопрос был про разницу между типом Integer и String почему бы не написать такой пример:

i : PInteger;

new(i);  
inc(i^);
dispose(i)

> тогда нафиг вообще эта обратная совместимость нужна?

Кому нужен потенциальный глюкодром? Глюкодром нужно избегать, а не поддерживать его. Иначе ж так и останется глюкодромом.


 
begin...end ©   (2005-03-14 11:30) [10]

> Defunct ©   (14.03.05 11:01) [9]

>> никаких конструкторов нет и в помине
>
> то что вы их не объявили, не означает невозможность
> написания слова constructor.

Разумеется. Вы можете объявить и вызвать в примере № 2 из [8] конструктор. Возможно, от этого Вам полегчает. Но пример будет работать точно так же, как и без конструктора. А зачем же его объявлять и вызывать, если и без него всё работает?

> Ведь фраза "в типе record нет методов", трактуется
> однозначно. Разницу чуете?

Я уже пояснил, что я говорил о встроенных конструкторах и деструкторах. Их в object"ах действительно нет. А фразу "в типе record нет методов" я не произносил, - Вы её придумали.

> Программа с обилием New/Dispose/GetMem/FreeMem разных
> каракулей типа шляпок и собачек на народном языке
> называется - глюкодром. Так что жалейте лучше себя.

Инструмент, допустивший много глюков в программе с New/Dispose на народном языке называется - кривые руки. Так что жалеть, всё-таки, следует именно Вас.

> Не переделывать, а сразу осознавая задачу и зная
> возможности использовать то, что больше всего
> подходит.

Э-э-э... Представьте, что в некоем старом исходнике из TP используются объекты, память под которые выделяется динамически. Так вот - я не понимаю, почему нужно переделывать весь код (превращать object в class, выбрасывать New и Dispose), когда можно оставить и так? А ведь Вы своей фразой из [7]: "Зачем с ним работать так? Если надо работать "так" так и создавать надо класс" именно такую переделку и предлагаете. Для того эта обратная совместимость и существует, чтобы ничего не переделывать, - по крайней мере, поначалу. А потом можно и переделать, но только не в статический object, а в class.

> Вы как раз лишаете, создавшего эту ветку, узнать
> возможности delphi.

Ни в коем случае. Автор может почитать данные ему советы и отфильтровать нужное для него, для его задачи. Даже без Вашей помощи. А ещё автор может заглянуть в справку, как ему и порекомендовали в [1]. Кстати, а Вы это уже сделали?


 
Defunct ©   (2005-03-14 12:12) [11]

> Разумеется. Вы можете объявить и вызвать в примере № 2 из [8] конструктор. Возможно, от этого Вам полегчает. Но пример будет работать точно так же, как и без конструктора. А зачем же его объявлять и вызывать, если и без него всё работает?

[8]
TFirstObject = object
  constructor Init;
  procedure MyProc; virtual;
end;

так есть конструктор или нет? Теперь читаем [3] "У object"ов нет конструкторов и деструкторов". теперь смотрим [8] - кто-то начал огрызаться, и на справку уповать.

> Я уже пояснил, что я говорил о встроенных конструкторах и деструкторах. Их в object"ах действительно нет.

Хотя мне честно сказать ваши пояснения совсем не нужны. Напомню что в [3] ничего не было пояснено.

> А фразу "в типе record нет методов" я не произносил, - Вы её придумали.

Все вам надо разжевывать.
Это моя фраза, и она верна, а ваша в [3] не верна, вот и разница.

> Инструмент, допустивший много глюков в программе с New/Dispose на народном языке называется - кривые руки.

Инструмент, допустивший много New/Dispose в программе на народном языке называется - кривые руки, а программа - глюкодромом. Так лучше звучит.


> Так что жалеть, всё-таки, следует именно Вас.
Бесплатную жалость в карман не положишь, высылайте пожертвования.

> Представьте, что в некоем старом исходнике из TP используются объекты, память под которые выделяется динамически.

Представил.

> Так вот - я не понимаю, почему нужно переделывать весь код (превращать object в class, выбрасывать New и Dispose), когда можно оставить и так?

Вообще-то при переносе из-под DOS в Win32 лучше пользоваться правилом - "выбрось и забудь". Также как и из Win32 в DOS.
А не поступать как предлагаете Вы - оставить. Оставить можно только глюкодром и потратить на него времени больше чем на написание нового модуля.

> А ведь Вы своей фразой из [7]: "Зачем с ним работать так? Если надо работать "так" так и создавать надо класс" именно такую переделку и предлагаете.

До сих пор не умеете читать? Или правда настолько зазубрились, что поверили собственному трактованию моей фразы? Я уже об этом вам сказал в [9].

> Для того эта обратная совместимость и существует, чтобы ничего не переделывать, - по крайней мере, поначалу. А потом можно и переделать, но только не в статический object, а в class.

Пять баллов. Так кто переделку предлагает? Вы в своих мыслях заблудились.

> Ни в коем случае. Автор может почитать данные ему советы и отфильтровать нужное для него, для его задачи. Даже без Вашей помощи. А ещё автор может заглянуть в справку, как ему и порекомендовали в [1].

С такой кашей что вы тут нагородили, мне бы было трудно понять разницу между классом и объектом.

> Кстати, а Вы это уже сделали?
Я что попугай?


 
begin...end ©   (2005-03-14 12:40) [12]

> Defunct ©   (14.03.05 12:12) [11]

> [8]
> TFirstObject = object
>  constructor Init;
>  procedure MyProc; virtual;
> end;

Перечитайте фразу, на которую отвечаете. Я говорил про пример [2]. Считать умеете?

> Напомню что в [3] ничего не было пояснено.

Это я и без Вас помню. Однако уже в [8] я это пояснил. Что же ещё нужно-то?

> Инструмент, допустивший много New/Dispose в программе
> на народном языке называется - кривые руки, а
> программа - глюкодромом. Так лучше звучит.

Как Вам будет угодно.

> Бесплатную жалость в карман не положишь, высылайте
> пожертвования.

На Ваше лечение? Боюсь, понадобится слишком много денег, а у меня их нет.

> Вообще-то при переносе из-под DOS в Win32 лучше
> пользоваться правилом - "выбрось и забудь". Также как
> и из Win32 в DOS.

Вообще-то в Win32 про object"ы следует вообще забыть. И именно потому, что они пока оставлены для обратной совместимости. Не удивлюсь, если скоро их выкинут. И на это недвусмысленно намекает Borland: "Object types are supported for backward compatibility only. Their use is not recommended.". Заметьте, что я ни разу не посоветовал их использовать, а Вы только это и делаете, напр.: "может возникнуть необходимость объединения небольшого кол-ва полей и методов работы с ними и не заботиться о выделении памяти под них (вот тут object и будет лучшим решением)".

> Я что попугай?

Нет, Вы просто не в себе.

---------------------------

И вообще, Defunct - я не вижу ни одной ошибки в [3], кроме отсутствия уточнения насчёт встроенных конструкторов. Это уточнение я уже сделал, поэтому смысла в обсуждении моих ошибок я не вижу. Потому что их здесь нет. К тому же, слушать чепуху, которую Вы несёте, мне уже поднадоело. Так что дальше можете разговаривать сами с собой. Удачи.


 
Defunct ©   (2005-03-14 13:12) [13]

> Перечитайте фразу, на которую отвечаете. Я говорил про пример [2]. Считать умеете?

А сами-то вы собственную фразу прочитали?
Там написано: "Вы можете объявить и вызвать в примере № 2 из [8] конструктор"
Вот я его объявил (пока что не вызывал). Мне полегчало (как там и было написано).
Вывод: вы просто непомните то, что пишете...

> Удачи.

Взаимно.


 
capkoh   (2005-03-14 21:20) [14]

Я понял, что ничего не понял!
Почитал справку, понял, что object"ы не рекомендуется использовать (ну и тут тоже писали) <что-то еще понял>, но главного так и не понял:

Зачем, все-таки, нужны "встроенные" в class методы (см. [0])?


 
jack128 ©   (2005-03-14 22:09) [15]

capkoh   (14.03.05 21:20) [14]
нужны "встроенные" в class методы (см. [0])?

Они не встроены, а унаследованы от одщего предка всех классов - TObject.
Эти методы осуществляют поддержку некоторых фич языка, касаемых классов, а именно: RTTI, динамическое распределение памяти под экземпляр класса, поддержка наследования от интерфейсов и обработка сообщений.


 
capkoh   (2005-03-14 22:25) [16]

Где можно об этом узнать подробнее?
Так, чтоб понятно было и все рассмотрено?


 
X_Tra   (2005-03-14 22:31) [17]

> Потому что у object"ов нет общего предка, в отличие от классов
> (для последних общим предком является TObject, в котором
> конструктор и деструктор уже есть)

Небольшое пояснение. Насколько я знаю, следующие два куска кода идентичны с точки зрения компилятора:


type TMyNewObject=class(TObject)
(...)
end



type TMyNewObject=class
(...)
end


А про то, зачем нужен TObject и его методы, можно прочитать в справке

> > Программа с обилием New/Dispose/GetMem/FreeMem разных
> > каракулей типа шляпок и собачек на народном языке
> > называется - глюкодром. Так что жалейте лучше себя.
> Инструмент, допустивший много глюков в программе с New/Dispose
> на народном языке называется - кривые руки. Так что жалеть,
> всё-таки, следует именно Вас.

Да, действительно, глюков в такой программе может быть много, но если всё аккуратно рассчитать, то ошибок не будет: проверено на собственном опыте:)


 
jack128 ©   (2005-03-14 22:43) [18]

capkoh   (14.03.05 22:25) [16]
Как ни странно, все расписано по F1


 
Дмитрий Мыльников   (2005-03-14 23:00) [19]

Встроенные в TObject методы нужны для получения информации о классе и его published свойствах во время работы программы (так называемый механизм RTTI - run time type information, который используется, в частности, в Object Inspector самой среды Deplhi).

И вообще, если ты не пользуешь старые прикладные библиотеки, которые писались ещё во времена Borland Pascal, то просто забудь про object и разбирайся с тем, как работает соврменная библиотека VCL. ИМХО, это более полезное занятие. :)



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2005.03.27;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.55 MB
Время: 0.037 c
1-1110625305
iffi
2005-03-12 14:01
2005.03.27
Окно поверх всех других!


1-1110433767
Alexandr3
2005-03-10 08:49
2005.03.27
AccessViolation непонятно с чего


1-1110630206
redlord
2005-03-12 15:23
2005.03.27
ошибка при удалении из Tstringlist


3-1109173447
Cardinal
2005-02-23 18:44
2005.03.27
Удаление записей из TTable


3-1109253535
Alex_V
2005-02-24 16:58
2005.03.27
Доступ к базам Clarion





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский