PDA

View Full Version : وراثت در دلفی



leila.66
پنج شنبه 17 آذر 1390, 19:48 عصر
سلام:
وراثت در دلفی چطوریه

در دلفی وراثت فقط به صورتpublicامكانپذير هست؟
یه سوال بی ربط با این موضوع هم دارم
چرا جاوا از دلفی قدرتمند تره؟

BORHAN TEC
جمعه 18 آذر 1390, 09:54 صبح
در دلفی وراثت فقط به صورتpublicامكانپذير هست؟
تا حدود زیادی می توان گفت بله. در این مورد بین زبانی مثل دلفی و زبانی مثل C++ تفاوتهایی وجود دارد.

چرا جاوا از دلفی قدرتمند تره؟
اینطور نیست که بگوییم جاوا از دلفی قدرتمندتر هست و یا بر عکس. مساله اینجاست که هر کدام در حوزه های کاری مشخصی ممکن است عملکرد بهتری نسبت به دیگری را به نمایش بگذارد.

یوسف زالی
جمعه 18 آذر 1390, 10:35 صبح
جناب عشایری برطبق چه سندی می گید پابلیک؟
یا شاید منظورتون چیزی فراتر از private, protected, ... اینهاست؟
اگر ممکنه توضیح بدید. ممنون

leila.66
جمعه 18 آذر 1390, 11:38 صبح
یعنی می تونیم بگیم فقط public هست؟

BORHAN TEC
جمعه 18 آذر 1390, 12:46 عصر
یعنی می تونیم بگیم فقط public هست؟
نه، منظور من چیز دیگری است که توضیح می دهم.

جناب عشایری برطبق چه سندی می گید پابلیک؟
یا شاید منظورتون چیزی فراتر از private, protected, ... اینهاست؟
بله، منظور چیز دیگری است.

توضیح:
در زبانهایی مثل C++‎‎‎‎ شما می توانید از یک کلاس به صورت public، private و protected ارث بری کنید در صورتی که در دلفی چنین امکانی وجود ندارد.

به عنوان نمونه به مثال زیر در زبان C++‎‎‎‎ توجه کنید:
class TChild: private TBase{
...
}

در مثال بالا میتوان به چند نکته اشاره کرد:

الف- اگر ارث بری به صورت private باشد (مثل مثال بالا) تمامی عناصر public و protected کلاس پایه به عناصر private کلاس TChild تبدیل می شوند و عناصر private کلاس پایه هم در کلاس جدید قابل دسترس نیستند.
ب- اگر ارث بری به صورت public باشد، عناصر public مربوط به کلاس پایه در کلاس جدید به صورت public، عناصر protected به صورت protected و عناصر private نیز در کلاس جدید قابل دسترس نیستند.
ج- اگر ارث بری به صورت protected باشد، عناصر public و protected کلاس پایه به صورت protected در کلاس جدید قرار خواهند گرفت و عناصر private هم در کلاس جدید قابل دسترس نیستند.

نتیجه:
البته با تمام این اوصاف حقیقت امر این است که این مساله در دنیای واقعی نمی تواند برای یک برنامه نویس دلفی مشکلی را ایجاد کند چون برنامه نویس دلفی از ابتدا بر طبق این مساله رفتار خود را سازماندهی خواهد کرد.

یوسف زالی
جمعه 18 آذر 1390, 13:52 عصر
یه سوال بی ربط که به نظرم ارزش یک تاپیک جدا رو نداشت:
کلاس های sealed رو در دلفی چطور پیاده می کنند؟ ورژن 7 خصوصا.
یه چیزهایی در رابطه با final شنیده بودم اما فکر می کنم برای جاوا باشه. تو دلفی نتونستم معادلی براش پیدا کنم.
ضمنا تمام اون کارهای مورد اشاره شما رو هم در دلفی می شه پیاده کرد. البته با تعریف مجدد سطح دسترسی.

BORHAN TEC
جمعه 18 آذر 1390, 14:19 عصر
کلاس های sealed رو در دلفی چطور پیاده می کنند؟ ورژن 7 خصوصا.
در دلفی 7 نمی توان این کار را انجام داد ولی در نسخه های جدیدتر باید از کدی مثل این استفاده کنید.
مثال:
type
TBaseClass = class sealed(TObject)
public
procedure MyMethod;
end;

TChild = class(TBaseClass); // ERROR!

یه چیزهایی در رابطه با final شنیده بودم اما فکر می کنم برای جاوا باشه. تو دلفی نتونستم معادلی براش پیدا کنم.
اشتباه می کنید. متد های final در دلفی هم وجود دارد ولی این موضوع به نسخه های جدیدتر دلفی مربوط می شود.
مثال:
TMyClass = class
procedure MyMethod; virtual;
end;

TChildClass = class(TMyClass)
procedure MyMethod; override;
end;

TAnotherClass = class(TChildClass)
procedure MyMethod; override; final;
end;

ضمنا تمام اون کارهای مورد اشاره شما رو هم در دلفی می شه پیاده کرد. البته با تعریف مجدد سطح دسترسی.
امکان داره مثال بزنید؟؟؟ :متفکر:

یوسف زالی
جمعه 18 آذر 1390, 20:56 عصر
شاهین جان فکر کنم اطلاعاتم کمی نم کشیده!
یادمه همچین کدی جواب می داد اما الان نمی ده!
اثرات استفاده نکردن از وراثت در دراز مدت! :لبخندساده:

C1 = class
private
FProp1: integer;
procedure SetProp1(const Value: integer);
public
property Prop1: integer read FProp1 write SetProp1;
end;
C2 = class(C1)
private
property Prop1;
end;

الان در این کد شی از نوع C2 نباید Prop1 رو می دید اما می بینه.
دلیلش هم اینه که Scope رو با Override کردن فقط می شه افزایش داد و حق با شماست.

Help:
An override can replace an inherited access specifier, add a missing specifier, or increase a property's visibility, but it cannot remove an access specifier or decrease a property's visibility.

vcldeveloper
جمعه 18 آذر 1390, 23:38 عصر
الان در این کد شی از نوع C2 نباید Prop1 رو می دید اما می بینه.
نباید میدید؟ چرا؟! خصوصیت در کلاس C1 به صورت public تعریف شده، پس C2 که فرزند C1 هست، باید بتونه اون رو ببینه، که میبینه. حتی اگر C2 فرزند C1 هم نبود، Prop1 و حتی FProp1 رو می دید؛ چون این دو کلاس در یک یونیت تعریف شدند و به قول ++C با هم friend هستند، مگر اینکه FProp1 به صورت strict private تعریف می شد.

روش دلفی برای جلوگیری از کاهش Scope در کلاس های فرزند به اصول طراحی نزدیک تر هست؛ چون وقتی یک طراح در کلاس خودش عضوی رو public تعریف میکنه، یعنی میخواد که اون عضو همیشه در دسترس باشه. کلاس فرزندی که Scope یک عضو را کاهش میده، پیش فرض طراح کلاس پایه را نقض میکنه، که این کار جالبی نیست. مثلا شما انتظار دارید که هر کلاسی که از TComponent مشتق میشه، خصوصیت Name داشته باشه، و بر همین اساس هم کد Polymorphic می نویسید، مثلا:


if Sender is TComponent then
TComponent(Sender).Name := 'MyNewName';

حالا اگر قرار باشه که شما یک کامپوننت بسازید، و برای خودتون خصوصیت Name را به سطح Private منتقل کنید، پیش فرض های طراح کلاس TComponent و استفاده کنندگان از کامپوننت های دلفی را نقض می کنید، و کد بالا دیگه کار نخواهد کرد!

یوسف زالی
شنبه 19 آذر 1390, 15:12 عصر
جناب کشاورز درست می فرمایید اما در همون پست عرض کردم که اشتباه می کردم.
help رو هم گذاشتم.
خق با شماست.