PDA

View Full Version : تفاوت new کردن با ساخت نمونه از کلاس



negar.rafie
یک شنبه 30 آبان 1395, 10:48 صبح
سلام
ی سوالی همیشه ذهن منا درگیر خودش کرده اینه که مثلا ببینید ما میخوایم از کلاس label استفاده کنیم:
حالا فرق
Label lblText


با

Label lblText=new Label ()

ASKaffash
یک شنبه 30 آبان 1395, 11:05 صبح
سلام
شکل اول به null اشاره می کند و در واقع هنوز کلاس سازنده نمونه ای از شی را ایجاد نکرده است ولی در حالت دوم کاملا" شی ساخته شده و مقایر پیش فرض کلاس در شی اعمال شده است

negar.rafie
یک شنبه 30 آبان 1395, 14:53 عصر
ممنون
حالا باید از کدوم استفاده کنیم؟
روش دوم؟
یا نه از هر کدوم در یک جای به خصوص؟

m2011kh
یک شنبه 30 آبان 1395, 15:26 عصر
ممنون
حالا باید از کدوم استفاده کنیم؟
روش دوم؟
یا نه از هر کدوم در یک جای به خصوص؟

سلام.

در اصل بهتره که یک رجوع به آموزهای برنامه نویسی شیء گرا بکنید. مطمئناً توضیحات کامل و پایه ای تری رو پیدا میکنید.

ولی این خط:
Label lblText
در واقع یک ارجاع کننده از نوع کلاس Label ایجاد میکنه ولی این ارجاع کننده در واقع خالی یا Null هست و به هیچ چیزی اشاره نمیکنه هنوز.

و این خط:
Label lblText=newLabel ()

ارجاع کننده ای از نوع کلاس Label ایجاد میکنه و اون رو ارجاع میده به شیء جدیدی که از کلاس Label میسازه.

و حالا کجا استفاده میشه:

مثلا من در یکی از ماژول هام میخوام در توابع مختلفی از یک شیء استفاده کنم. باید داخل اون ماژول در قسمتی که رفرنس ها و متغیر های کلی رو تعریف میکنم این ارجاع دهنده رو هم تعریف کنم. و بعداً اونو توی یکی از تابع ها به یک شیء ارجاع بدم. یه تصویر به عنوان مثال:

143562

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

ولی mainLabel2 توی رویداد کلیک قابل دسترسی نیست چرا که فقط توی رویداد Form_Load تعریف شده و خارج از اون اعتباری نداره.

امیدوارم که پاسختون رو دریافت کرده باشید.

موفق و سربلند باشید.

negar.rafie
یک شنبه 30 آبان 1395, 21:05 عصر
راستش متوجه نشدم کجا باید از کدوم استفاده کرد

m2011kh
یک شنبه 30 آبان 1395, 22:34 عصر
راستش متوجه نشدم کجا باید از کدوم استفاده کرد

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

ولی در کل:

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

متأسفانه نمیتونم بهتون مرجع یا کتابی رو معرفی کنم چون مراجعی که من توی ذهنم دارم به زبان آلمانی هستن. ولی با یه سرچ ساده توی گوگل میتونید پی دی اف های خوبی رو درباره برنامه نویسی شیء گرا و نحوه پیاده سازیش در C# پیدا کنید.

امیدوارم که توضیحاتم مفید بوده باشه.

موفق و سربلند باشید.

ali_md110
دوشنبه 01 آذر 1395, 08:11 صبح
راستش متوجه نشدم کجا باید از کدوم استفاده کرد
هر زمان که نیاز به یک شی نداریم پس نباید وهله سازی یا new بکنیم
بدلیل مصرف حافظه
بی خودی در بخش جنرال یا عمومی یا هرجای دیگه یک شی رو new نکنید و در هر جا که نیاز هست اینکار رو بکنید
یک مثال
فرض کنید شما یک آشپز هستید برای پختن پلو یک کیسه برنج توی آشپزخانه دارید هر زمان نیاز دارید سر کیسه برنج رو باز میکنید و مقدار لازم رو بر میدارید یعنی new سازی میکنید
و بعد از استفاده ممکنه سر کیسه برنج رو می بندید تا سوسک توی اون وارد نشه یا برنج هاتون روی زمین نریزه و دست و پاگیر نشه

negar.rafie
دوشنبه 01 آذر 1395, 08:43 صبح
ممنون
من شی گرایی را خوندم
این سوال را هیجا نتونستم پیدا کنم
اخه با هر دو روش ما میتونیم به تماس خاصیت ها و موارد دیگه دسترسی پیدا کنبم
حالا جناب ali_md110 کلا سوالی که اینه که
ما همیشه باید از روش دوم استفاده کنیم دیگه درسته؟ولی نباید به صورت سراسری new کنیم و هر جا نیاز داریم درسته؟

ali_md110
دوشنبه 01 آذر 1395, 09:31 صبح
همیشه نه
بعضی اوقات نیاز هست یک شی در یک جایی تعریف و درجای دیگه مقدار دهی یا وهله سازی و استفاده بشه
اگر مبحث dependency injection رو مطالعه کنید روشهای تزریق وابستگی یا رفع نیازهای یک برنامه رو بهتر میتونید پیاده سازی کنید

negar.rafie
دوشنبه 01 آذر 1395, 10:14 صبح
ببنیید
کلا سوال من اینه که
چرا هم زمانی که new میکنیم هم نمیکنیم میتونید به تمام خاصیت ها و موارد دیگه اون کلاس دسترسی داشته باشیم؟
حالا کدوم روش درسته
متوجه نمیشم به خدا

Mahmoud Zaad
دوشنبه 01 آذر 1395, 11:10 صبح
سلام
درسته وقتی مثلا Label lbl1; تعریف میشه به تمام خاصیتهاش دسترسی داریم ولی ازشون نمی تونیم استفاده کنیم و اگر استفاده کنیم خطای null بودن می گیریم. شما همین چیزی که می گید رو امتحان کنید مثلا لیبلی که در بالا نوشتم رو در قسمت سراسری فرم تعریف کنید بعد در کلیک یک دکمه بنویسید lbl1.Size = new Size(50, 50); حالا برنامه رو اجرا کنید و روی دکمه کلیک کنید با خطای زیر مواجه میشید: Object reference not set to an instance of an object. یعنی شما هنوز یک نمونه از اون شی رو تعریف نکردید فقط اسمش رو معرفی کردید. البته ویژوال استودیو قبلش یه خط قرمز زیر lbl1 میکشه که نشون میده هنوز نمونه ای ازش ساخته نشده.
حالا تعریف لیبل در قسمت سراسری رو به صورت Label lbl1 = new Label(); بنویسید برنامه رو اجرا کنید و روی دکمه کلیک کنید. این بار خطایی نمیده یعنی کار درست انجام شده.(البته لیبلی نمایش داده نمیشه چون باید لیبل به فرم اضافه بشه که فعلا با این مساله کاری نداریم)
دوستمون مثال خوبی زدن حالا من یه جور دیگه میگم شما فرض کنید یه گوشی خریدید هنوز توی جعبه است باطری، شارژر، هدفون، نرم افزار، سخت افزار، خلاصه همه چی داره ولی تا وقتی که جعبه رو باز نکنید نمی تونید ازش استفاده کنید. اینجا هم همین مساله است کلاس Label همه خواص رو داره ولی تا وقتی که یک نمونه ازش نسازید (new نشه) نمی تونید ازش استفاده کنید.
یه سری توضیح هم اینجا (http://barnamenevis.org/showthread.php?532649-%D8%AA%D9%81%D8%A7%D9%88%D8%AA-%D8%AA%D8%B9%D8%B1%DB%8C%D9%81-%D8%B4%D8%A6-%D8%AF%D8%B1-%DB%8C%DA%A9-%D8%AE%D8%B7-%D8%A8%D8%A7-%D8%AA%D8%B9%D8%B1%DB%8C%D9%81-%D8%AF%D8%B1-%D8%AF%D9%88-%D8%AE%D8%B7) نوشتم می تونید بخونید.

*****
یه مساله دیگه؛ همونطور که می دونید فرق سیستم با انسان اینه که سیستم مثل یک بچه تازه متولد شده است (حتی بدتر، چون انسان به طور غریزی یکسری آپشن روش نصبه!) که باید همه چیز رو به طور دقیق بهش بگیم یعنی وقتی ما یک گوشی می خریم می دونیم که گوشی رو می خریم که استفاده کنیم ولی سیستم این رو متوجه نمیشه و باید دقیقاً بهش بگید که ما یک گوشی خریدیم، ما در حال استفاده از گوشی هسیتم و ... یعنی من و شما می دونیم که وقتی Label lbl1; رو تعریف می کنیم این رو برای استفاده تعریف می کنیم ولی سیستم این رو متوجه نمیشه و باید بهش بگید که lbl1=new Label(); یعنی اون لیبل رو تعریف کردیم که ازش استفاده کنیم. بنابراین وقتی دارید برنامه می نویسید فکر کنید دارید به یه بچه تازه متولد شده (که هیچ درکی از این دنیا نداره و تازه وارد این دنیا شده) چیزی یاد می دید. دقیق و ریز به ریز

negar.rafie
دوشنبه 01 آذر 1395, 14:06 عصر
ممنون
توضیحات کامل و جامع بود
اخه میدونید من کجا به شک افتادم
بذارید مثال بزنم شاید بهتر متوجه بشید
فرض کنید ما در فرم1 یک لیبل داریم و میخوایم متن اون را از فرم2 تغییر بدیم:

private void button1_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2(label1);
f2.Show();
}

اینم کدهای فرم 2
public Form2(Label lbl)
{
InitializeComponent();
lblDate = lbl;
}
Label lblDate;
// Label lblDate = new Label();
private void button1_Click(object sender, EventArgs e)
{
lblDate.Text = DateTime.Now.ToString();
}


در این فرم 2 ما ی لیبل به صورت سراسری به هر 2 روش ایجاد کردیم
حالا من میگم به هر روش استفاده بشه جواب میده و خطایی نمیده
فرقشون چیه
روش صحیح کدومه
منظورم در اینطور موارد هستش

Mahmoud Zaad
دوشنبه 01 آذر 1395, 15:47 عصر
اینجا مساله فرق میکنه، چون شما دارید لیبلی که در فرم دو هست رو برابر یک لیبل ساخته شده در فرم یک قرار می دید یعنی لیبل در فرم یک ساخته شده و در فرم دو دیگه نیاز نیست دوباره ساخته (new) بشه.

negar.rafie
دوشنبه 01 آذر 1395, 18:52 عصر
ممنون
کلا سوالم همین بود
ممنون از همگی که مثل همیشه پاسخ دادید
عالی بود
لایک

Mahmoud.Afrad
دوشنبه 01 آذر 1395, 19:16 عصر
در مورد نوع داده ارجاعی مطالعه کنید. در آدرس زیر شکلها گویا هست.
http://www.codeproject.com/Articles/76153/Six-important-NET-concepts-Stack-heap-value-types

عملیات کپی، در نوع داده‌ی ارجاعی را مطالعه کنید
http://www.dotnettips.info/post/2331/%D8%A8%D8%B1%D8%B1%D8%B3%DB%8C-%D9%85%D9%81%D8%A7%D9%87%DB%8C%D9%85-%D9%85%D8%AA%D8%BA%DB%8C%D8%B1%D9%87%D8%A7%DB%8C-value-type-%D9%88-reference-type-%D8%AF%D8%B1-%D8%B3%DB%8C-%D8%B4%D8%A7%D8%B1%D9%BE