PDA

View Full Version : کلاسها و شی ها در فاکس پرو



rezaTavak
پنج شنبه 27 دی 1386, 11:20 صبح
شاید اولین تفاوت مهمی که در فاکس داس و ویندوز وجود دارد همین باشد.

اما این دو واقعا چه هستند؟

در برنامه نویسی جدید تولید برنامه بدون کلاس ممکن نیست. .net بر پایه کلاسهاست و Java در درون کلاس خلاصه شده است و از آن هم بهتر:
همه چیز در Ruby شی است. حتی اعداد!


آیا کلاس و شی یکی هستند؟ خیر.

اما چرا آنها را یکی میدانند؟

چون شی از روی کلاس ساخته می‌شود. کلاس وجود خارجی ندارد و مانند این است که ما بگوییم Integer اما Object وجود خارجی دارد و مثل این است که بگوییم عدد ۲.




ساده ترین کلاس کلاسی است بدون چیزی در آن.

و در هر کلاس مشخصه و متد وجود دارد.



کلاس می تواند از روی کلاسی دیگر ساخته شود و کلاس ساخته شده تمام خواص کلاس قبلی را دارد.




کلاس دارای دو نوع متغیر و متد از نظر دسترسی است:
عمومی Public یا Private یا خصوصی

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

البته در جاوا نوع دیگری هم داریم که دوستانه نام دارد و هر جایی داخل یک فایل است.





خب برای ساخت یک کلاس مانند زیر عمل می کنیم:


DEFINE CLASS class1 AS CUSTOM
ENDDEFINE

در فاکس پرو این دستور کلاس شما را می سازد. که نام کلاس در اینجا class1 است و از قوانین نام گذاری متغیرها در فاکس تبعیت میکند و نوع کلاس با AS مشخص شده که در اینجا CUSTOM است. یعنی اینکه هر کلاسی از روی یک کلاس دیگر باید ساخته شود که از قبل در زبان برنامه نویسی آن تعبیه شده است. مثلا در java تمام کلاسها شاخه ای ازکلاس پایه Object هستند.

در اینجا ما هیچ نساخته ایم فقط گفتم که شکل کلاس چگونه باشد مثل این است که نقشه یک خانه را داده باشیم اما ساخت آن:


obj1= CREATEOBJECT("class1")


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

دقت کنید که کلاس باید داخل فایل prg تعریف شود و با دستور set procedure فایل prg معرفی شود.

rezaTavak
دوشنبه 01 بهمن 1386, 11:11 صبح
تا بحال با خواسته اید که با تاریخها کار کنید؟

من در برنامه نویسی تابعی بعنوان رشته ذخیره کرده و با توابع آنها را دستکاری میکنم اما ببینید این برنامه چگونه عمل میکند:




o=CREATEOBJECT("dates")
?ShowDate(o)

FUNCTION ShowDate
LPARAMETERS DATES
RETURN ALLTRIM(STR(DATES.Year))+"/"+ALLTRIM(STR(DATES.Month))+"/"+ALLTRIM(STR(DATES.Day))
ENDFUNC



**************************************************
*-- Class: dates (d:\program files\microsoft visual foxpro 9\vcxs.vcx)
*-- ParentClass: custom
*-- BaseClass: custom
*-- Time Stamp: 01/21/08 11:19:11 AM
*
DEFINE CLASS dates AS custom


Height = 33
Width = 82
year = 2000
month = 1
day = 1


*-- XML Metadata for customizable properties
_memberdata = .F.

PROCEDURE getyear
RETURN THIS.Year
ENDPROC


PROCEDURE getmonth
RETURN THIS.Month
ENDPROC


PROCEDURE getday
RETURN THIS.Day
ENDPROC


ENDDEFINE
*
*-- EndDefine: dates
**************************************************





جالبه نه؟
ارسال شی به تابع به جای چیزهایی که تا امروز ارسال کرده ایم (شاید هم قبلا کار کرده باشید)


ما این شی را ادامه خواهم داد و کاری میکنیم که شما از آن انتظار دارید! یعنی یک شی که کار توابعی که تا حال داشته ایم را انجام دهد.

rezaTavak
سه شنبه 02 بهمن 1386, 08:53 صبح
امروز چند نکته را بررسی میکنیم:

۱ - اگر متغیری یا متدی در کلاس بخواهیم از تعییر مصوب بماند از کلمه کلیدی PROTECT استفاده میکنیم چرا؟

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


۲ - هر گاه کلاسی ساخته شود اولین متدی که اجرا شود Init است اگر هر پارامتری به کلاس ارسال شود به این متد ارسال شده و در این متد قابل دسترسی است.

به مثال تغییر داده شده بالا نگاه کنید:


o=CREATEOBJECT("dates",2008,1,21)
?ShowDate(o)
?o.toDate()
FUNCTION ShowDate
LPARAMETERS DATES
RETURN DATES.julianday()
ENDFUNC



**************************************************
*-- Class: dates (d:\program files\microsoft visual foxpro 9\vcxs.vcx)
*-- ParentClass: custom
*-- BaseClass: custom
*-- Time Stamp: 01/21/08 11:19:11 AM
*
DEFINE CLASS dates AS custom
PROTECTED year
PROTECTED month
PROTECTED day
PROTECTED DELIMETER
PROTECTED Date

DELIMETER = "/" && Date Delimeter

PROCEDURE Init
LPARAMETERS tnYear, tnMonth, tnDay
THIS.Year = tnYear
THIS.Month = tnMonth
THIS.Day = tnDay
ENDPROC

PROCEDURE getyear
RETURN THIS.Year
ENDPROC


PROCEDURE getmonth
RETURN THIS.Month
ENDPROC

PROCEDURE getday
RETURN THIS.Day
ENDPROC

PROCEDURE julianday
RETURN SYS(11,THIS.toDate())
ENDPROC

PROCEDURE toDate
lnPreDateFormat = SET("Date")
SET DATE YMD
THIS.Date=CTOD(ALLTRIM(STR(THIS.Year))+THIS.DELIME TER+ ;
ALLTRIM(STR(THIS.Month))+THIS.DELIMETER+ ;
ALLTRIM(STR(THIS.Day)))
SET DATE &lnPreDateFormat
RETURN THIS.Date
ENDPROC


ENDDEFINE
*
*-- EndDefine: dates
**************************************************

rezaTavak
چهارشنبه 03 بهمن 1386, 10:02 صبح
خب حال فرض می کنیم که یک Object از روی یک کلاس ساخته باشیم به اسم Obj1 میتوانیم با دستور زیر یک کپی از آدرس این شی را داشته باشیم



obj2 = obj1


یعنی اینکه علامت تساوی در شی این معنی را میدهد که میتوان دو اسم از یک شی داشت.



در مثال پست قبلی اگر اینگونه عمل کنیم:


o1 = o


میتوانیم دیگر به جای o از o1 استفاده کنیم و یک شی دارای دو اسم می شود.

rezaTavak
شنبه 06 بهمن 1386, 17:12 عصر
کلاسها بر دو نوعند:

کلاسهای Container و ساده.

مثلا فرم یک کلاس از نوع محتوی (Container) است. که می تواند در خودش شئی را یدک بکشد.

مثلا کلاس زیر یک فرم و یک دکمه دستور دارد که این دکمه دستور در موقع تعریف کلاس با add object به آن اضافه شده است:


DEFINE CLASS newForm AS Form


Width = 200
Height = 200
Name = "c"


ADD OBJECT command1 AS commandbutton WITH ;
Top = 48, ;
Left = 48, ;
Height = 27, ;
Width = 84, ;
Caption = "Command1", ;
Name = "Command1"


ENDDEFINE


به کلاس دقت کنید که چگونه شی اضافه شده دارای مشخصاتی است که با with داده شده و بین آنها کاما قرار گرفته است.

rezaTavak
یک شنبه 07 بهمن 1386, 09:20 صبح
کار کردن در حالت کد کمی سخت است بهتر است من البعد در محیط ویزوال بررسی کنیم. و سپس کد تولید شده را مشاهد کنیم:

برای تولید یک کلاس از کد:



create class


استفاده می شود که پس از تایپ فرمان فوق و کلید اینتر یک پنجره باز میشود که نام کلاس و کلاسی که باید از روی آن ساخته شود (کلاس پدری) و محل ذخیره در فایل vcx یا کتابخانه کلاسها از شما خواسته می شود. (اگر کلاس پدری از نوع OleControl باشد پس از انتخاب لیست کلاسهای ویندوز نمایش داده خواهد شد )


پس از انتخاب و جایگزینی تمام چیزهای خواسته شده کلاس پیش فرض ساخته می شود.

اما کلاس پیش فرض چیست؟

یعنی اینکه مثلا طول و عرض آن از پیش عددی انتخاب شده یا برخی از چیزها پیش فرض در نظر گرفته میشود. اگر چیزی پیش فرض باشد و عوض نشود فونت نازک است اما اگر حتی آنرا عوض کنید و یا روی مقدار اینتر بزنید آن فونتش تیره خواهد شد. که نشان می دهد کلاس دیگر نباید از مقادیر پیش فرض استفاده کند.


بعد از ذخیره کلاس از منو tools/class browser را انتخاب کنید. سپس یک پنجره باز میشود روی آیکن open کلیک کرده و یک کلاس انتخاب کنید.

باز زدن دکمه View Class code کلاسی که انتخاب کرده اید بصورت کد نمایش داده می شود.

rezaTavak
یک شنبه 14 بهمن 1386, 10:08 صبح
شاید این را همه بدانند اما تذکر میدهم:

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

ارجاع به شی باید حتما از طریق آدرس آن صورت گیرد. آدرس مکانی از جافظه که شی در آن قرار دارد. دقیقا فرض کنید که شی مانند یک متغیر است.


اما اسامی میانبری هم وجود دارد. this به شی جاری اشاره میکند. یعنی شئی که این کد در آن قرار می گیرد. پس خارج از اشیا this معنی ندارد.

this.parent البته من این خصیصه خوب فاکس را در کلاسهای جاوا هم پیاده سازی کردم که اشاره به کشیی دارد که این شیء درون آن شیء است و فقط هنگامی معتبر است که این شی داخل شی دیگر باشد مانند دکمه دستور در فرم.

thisform به شی فرمی اشاره میکند که کنترل در آن است تمام اشیای روی فرم به آن دسترسی دارند حتی در متدهای فرم هم معتبر است.


پس o=this یعنی یک کسی از آدرس شی فعلی در o قرار گیرد.