Форум: "Основная";
Текущий архив: 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.028 c