مشکل هنگام پاس دادن مقدار بین کلاس ها

(ehsan)

Member
۲ تا کلاس دارم.
توی کلاس اول یک متغیری دارم به نام mynumber . توی همون کلا متغییر mynumberرا برابر با 32 قرار میدم.توی MouseEvent این کارو انجام میدم.

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

PHP:
public var myclass:ClassOne = new ClassOne();

حالا که مینویسم
PHP:
trace(myclass.mynumber);
مقداری توش نیست می زنه 0 یا NaN .

حالا اگه بجای اینکه توی MouseEvent این کارو انجام بدم و mynumber را مقدار دهی کنم توی خود تابع سازنده کلاس اول mynumber را مقدار دهی کنم. مقدار درونش قرار میگیره.

در واقع اینطور بگم. من می خوام مقدار متغییر کلاس اول را با MouseEvent تغییر بدم.به کلاس دوم پاس بدم.
اگه راهنمایی یا مثالی میتونید برام بزنید.
ممنون.
 

JavidFlasher

کاربر فعال
موس ایونت رو واسه چی میزاری؟
باید یه displayObjectاز کلاسهات به هم پاس بدیا!
ینی از کلاس دومت کانستراکتور یه آرگمان displayObjectبگیری وبعد اون بفرستی به کلاس اولیت و داخل کلاس اولیت یه لیسنر موس ایونت واسه همون displayobjectمبزاری.
 

(ehsan)

Member
من نمیدونم DisplayObject اینجا کارش چی هست ؟ من فقط یک عدد میخوام پاس بدم! MouseEvent را برای این میزارم چون با کلیک کردن Mouse این مقدار عوض میشه و بعد به کلاس دوم پاس داده میشه.

اگه میتونین یک مثال برای من کدی بزنین.
که داخل کلاس اول یک عدد توسط رویداد موس تغییر کنه و به کلاس دوم پاس داده بشه. ممنون
 

JavidFlasher

کاربر فعال
خب MouseEventباید یه targetداشته باشه ببینین

کلاس 1:
PHP:
package 
{
	import flash.display.DisplayObject;
	import flash.events.MouseEvent;

	public class ClassOne
	{
		public var mynumber:Number = 2;
		public function ClassOne(l:DisplayObject)
		{
			l.addEventListener(MouseEvent.CLICK,onClick);
			function onClick(e:MouseEvent):void
			{
				mynumber=6
			}

		}

	}

}

کلاس 2:
PHP:
package 
{
	import flash.display.DisplayObject;
	import flash.events.MouseEvent;

	public class ClassTwo
	{
		public var class1:ClassOne;
		public function ClassTwo(l:DisplayObject)
		{
			class1 = new ClassOne(l);
			l.addEventListener(MouseEvent.CLICK,onCLK);
			function onCLK(e:MouseEvent):void
			{
				trace(class1.mynumber);
			}

		}

	}

}

و نمونه سازی از کلاسمون و پاس دادان هدف برای کلیک شدن:
PHP:
var class2:ClassTwo=new ClassTwo(stage)
اینجا مقدار پیشفرض متغیر mynumberدو گذاشتیم که وقتی تو استیج کلیک میشه به 6تغییر میکنه!
فایل رو پیوست کردم باز کنین با کلیک تو صفحه عدد تغییر کرده رو توoutputببین
 

پیوست ها

  • classes.zip
    7.6 کیلوبایت · بازدیدها: 3

(ehsan)

Member
ممنون جاوید جان ، فقط می تونی توضیح بدی چرا اینکارو میکنیم ؟ چرا بصورت معمولی کار نمیده ؟ من زیاد با کلاس ها کار نکردم برا همین به این قضیه تاحالا برخورد نکردم. در واقع بجای اینکه به Stage رویداد اضافه کنیم داریم به DisplayObject رویداد اضافه میکنیم!

میتونی دلیلشو بگی ؟
 

(ehsan)

Member
الیته همون چیزی که حدس میزدم اتفاق افتاد.رفتم تست کردم. این باعث میشه الان روی هر MovieCLipهم کلیک میکنم چون از DisplayObject مشتق شده کد ما اجرا بشه.که من نمیخوام این اتفاق بیفته. باید چی کار کنم ؟
 

JavidFlasher

کاربر فعال
ببینین کلاس displayObjectمشتق شده EventDispatcherهستش برای همین باید یه هدف(target)داشته باشه !اگه نخوایم کلاسمون رو به صورت documents classاستفاده کنیم حتما باید یه targetاز اونجایی که کلاس تعریف میکنیم بفرستیم اگه میخوای از documnet classاستفاده کنی تا نخواد diplayObjectرو به صورت آرگومان بفرستی حتما باید کلاستو مشتق یه DisplayObjectکنی(معمولا Sprite)
من خودم اطلاعات چندانی ندارم به آموزشهای هادی یه نگاهی بنداز
 

clove-pink

کاربر فعال
۲ تا کلاس دارم.
توی کلاس اول یک متغیری دارم به نام mynumber . توی همون کلا متغییر mynumberرا برابر با 32 قرار میدم.توی MouseEvent این کارو انجام میدم.

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

PHP:
public var myclass:ClassOne = new ClassOne();
حالا که مینویسم
PHP:
trace(myclass.mynumber);
مقداری توش نیست می زنه 0 یا NaN .

حالا اگه بجای اینکه توی MouseEvent این کارو انجام بدم و mynumber را مقدار دهی کنم توی خود تابع سازنده کلاس اول mynumber را مقدار دهی کنم. مقدار درونش قرار میگیره.

در واقع اینطور بگم. من می خوام مقدار متغییر کلاس اول را با MouseEvent تغییر بدم.به کلاس دوم پاس بدم.
اگه راهنمایی یا مثالی میتونید برام بزنید.
ممنون.

سلام
شما مقدار متغیر مورد نظر تون رو تو function مربوط به کلیک ماوس تعریف کردین، و به احتمال زیاد قبل از اون هم این متغیر رو جای دیگه ای مقدار دهی نکردید.به خاطر همین هست که وقتی
PHP:
trace(myclass.mynumber);        [/PHP

این کد اجرا می شه مقدار NAN بهتون بر می گردونه.شما می خوایید دقیقا همون موقع که با ماوس روی ابجکت مورد نظر کلیک شد (یعنی همون کلاس اول) همزمان تو کلاس دوم بهش دسترسی پیدا کنید؟؟
اگه منظورتون این هست باید یه event خودتون بسازید توی کلاس اول و بعد در کلاس دوم گوش بدید که هر وقت اتفاق افتاد به مقدار متغیر مورد نظرتون دسترسی پیدا کنید.

یه نکته ای که من به ذهنم می رسه این هست که متغیر رو public تعریف نکنید چون این باعث می شه شاید ناخواسته در قسمت های دیگه برنامه تغییرش بدین،و شما این رو نخواید و تنها تو کلاس مورد نظر(کلاس 1) باید تغییر روش انجام بشه.
برای این کار از get استفاده  کنید تا متغیر رو بهتون بر گردونه.

یه نمونه اینجوری می شه:
[CODE]package  {
    import flash.display.Sprite;
    import flash.events.MouseEvent;
    import flash.display.Shape;
    import flash.events.Event;
    
    public class class1 extends Sprite{
        private var myVar:Number;
        private var myShape:Sprite;
        
        public function class1() {
            //keshidane shekli baraye rooydade clicke mouse
            myShape=new Sprite();
            myShape.graphics.beginFill(0xffcc00);
            myShape.graphics.drawCircle(100,100,15);
            addChild(myShape);
            myShape.addEventListener(MouseEvent.CLICK,onMouseClick);
            
            //meghdar dahi avalie 
            setVar(32);
        }
        public function get variable():Number{
            return myVar;
        }
        private function onMouseClick(e:MouseEvent):void{
            setVar(32);
            dispatchEvent(new Event("MouseClick"));
        }
        private function setVar(val:Number):void{
            myVar=val*Math.random();
        }

    }
    
}
[/CODE]توی این کلاس هم زمان که داره روی mouse  کلیک می شه یه event به نام "MouseClick"  ساختیم و حالا تو کلاس 2 یه listener براش می نویسیم و به مقدار مورد نظر دسترسی پیدا می کنیم.
اون متغیر هم private  میگیریم و با متد "public get variable " مقدارش رو قابل دسترس می کنیم.

این کلاس دوم
[CODE]package  {
    import flash.display.Sprite;
    import flash.events.Event;
    
    public class class2 extends Sprite {

        private var class1Instance:class1;
        
        public function class2() {
            class1Instance=new class1();
            class1Instance.addEventListener("MouseClick",showValue);
            addChild(class1Instance);
        }
        private function showValue(e:Event):void{
            trace(class1Instance.variable);
        }

    }
    
}
[/CODE]

روشی که آقا جاوید گفتند هم خیلی خوب و درست هست فکر می کنم و تنها کافیه شما به جای stage ، اون آبجکتی که قراره روش کلیک شه بهش پاس بدین.
 
آخرین ویرایش:

(ehsan)

Member
ممنون ، دست آخر هم باید ظاهرا براش function بنویسم.
بله دقیقا همینو می خواستم که به محض اینکه توی کلاس اول تغییرکرد توی کلاس دوم بهش دسترسی داشته باشم و روی اون عملیات انجام بدم.

/*-----------------------*/

حالا با این دو روشی که هم شما هم جاوید گفت ور میرم اگه سوالی بود می پرسم دوباره.
 

(ehsan)

Member
من به مشکلی بر خوردم با روش جاوید.
اینکه من کلاس هامو به MovieClip لینک میکنم. که باعث ایجاد Error میشه.
مثالو ضمیمه کردم اگه میشه یک نگاهی بکنین ، ممنون.
 

پیوست ها

  • bbb.zip
    10.4 کیلوبایت · بازدیدها: 8

JavidFlasher

کاربر فعال
اشیا استاتیک رو اگه اکلاسشون شی بسازی نمیشه دسترسی بهش داشت اما کلاس ها اونو به ارث میبرن و میتونن دسرسی پیدا کنن بهش :
PHP:
import com.ehsan.Globals
Globals.mynumber=2
 

++Hadi++

Active Member
مثل متغیر سراسری می مونه ...
کافیه تو یه کلاسی که برای share بین تمامی کلاسها تعیین می شه (تو اینجا مثلا کلاس Globals که نوشتم ) یه سری متغیر یا متد(تابع ) از نوع static تعریف کنید . اگه از این کلاس با دستور new نمونه سازی کنید ، اون شی به صورت جداگانه اونو به ارث نمی بره تا مثلا 20 تا شی مختلف هر کدوم یکی یه دونه از اونو داشته باشند تا مثلا بتونی به متغیر هر کدوم مقدار متمایز و منحصر به اون شی رو بدین . بلکه این متغیر در روت اون کلاس طراحی می شه تا فقط با اسم اصلی اون کلاس بتونین به اون متغیر دست پیدا کنین نه با اشیای ساخته شده از اون کلاس . بعد مثلا تو کلاس a ، کلاس Globals تو import می کنی و به متغیر استاتیک اون با اسم اصلی کلاس دست پیدا می کنی و مثلا اونو تغییر می دی . حالا اگه کلاس Globals رو تو کلاس B هم import کنی و بعد از تغییر متغیر استاتیک اون تو کلاس A ، تو کلاس B مقدار اونو تریس کنی می بینی که مقدار جدید رو بهتون می ده .
در واقع اگه تو محیط شبکه کار کنین مثل سروری می مونه که کارمندان شرکت ، فایل های مورد نیاز همدیگه رو تو اونجا share می کنن تا دیگران بتوننبه اونا دسترسی پیدا کنن و بتونن حتی اونا رو تغییر بدن . این نوع متغیر ها تو کل سیستم های OOp از انواع انجین های بازی و زبانهای بزرگ مثل جاوا و C++ و C# و ... همین کارآیی رو دارن و اگه public تعریف شن ، نقش متغیر سراسری رو به خودشون می تونن بگیرن . البته جزئیات بیشتری هم دارن اینکه مثلا اگه protected تعریف بشن ، یه سری کلاسهای فرزندی (زیر کلاسها) اونا رو به ارث می برن نه بقیه و .... ولی تا این حد فک کنم نیاز شما رو جواب می ده . ضمن اینکه باید بدونین ، متغیری که از نوع const یا ثابت باشه که دیگه اسمش متغیر (قابل تغییر) نمی شه رو فقط 1 بار می شه مقدار داد و دیگه نمی شه مقدارشو عوض کرد (فک کنم متغیر استاتیک رو با این اشتباه گرفتین ...)
دو تا نکته :
1- اگه متغیر استاتیکتونو از نوع object تعریف کنین خیلی عالی می شه چون n متغیر و تابع مختلف رو تو جاهای مختلف با اسامی متمایز بهش الحاق می کنین و از جاهای دیگه دریافت می کنین تا دیگه نیازی به زیاد کردن متغیر ها و متد های استاتیک تو کلاس سراسریتون نباشین و راحت فقط با کلاسهای اصلیتون سر و کار دشته باشین .( یه ابر یا یونولیتو در نظر بگیرین که هر کسی ، مقاله خاصی رو با سوزن ته گرد به اون می چسبونه و یه سری های دیگه مقاله مورد نیازشونو از اون دریافت می کنن و دیگه هی متغیر های استاتیکتون زیاد نمی شه )
2- شما اگه نیاز داشتین که یه تابعی رو بدون dispatch کردن رویدادی فراخوانی کنین کافیه یه متغیر از نوع Function از نوع استاتیک تو کلاس سراسریتون تعریف کنین و تابع مد نظر از کلاس خاصی مثل A رو در اون بریزین و هر جای دیگه از کلاس دیگه ای مثل B ، وقتی اتفاقی افتاد که خواستین تابع مد نظر تو کلاس A برای اشیای ساخته شده از کلاس A اجرا شه ، این متغیر Function سراسری رو اجرا کنین . دیگه از dispatch شدن رویداد جلوگیری کردین و خوبیش به اینه که به جای اینکه EventListener بزارین تا در هر لحظه سیستم کامپیوتر چک کنه که آیا رویداد مد نظر از بین مثلا 100000000 رویداد مختلف داده شده داره اجرا می شه یا نه (تا به نسبت اسم رویداد ، تابع و کار مورد نظر رو انجام بده) ،سیستم رو راحت تر و آزاد تر نگه دارین تا فقط در شرایط لازم ، یه تابع هدف رو به صورت مستقیم صدا بزنین .
این نکات می تونه یه سکوی پرتابی برای شما دوستان عزیز در راه برنامه نویسی OOP باشه .ضمن اینکه دستتونو تو انجام پروژه های بزرگ باز تر می کنه .
بای...
 

clove-pink

کاربر فعال
من به مشکلی بر خوردم با روش جاوید.
اینکه من کلاس هامو به MovieClip لینک میکنم. که باعث ایجاد Error میشه.
مثالو ضمیمه کردم اگه میشه یک نگاهی بکنین ، ممنون.

شما توی کلاس هاتون پارامتر پاس دادین در حالی که نمونه از اون کلاس در stage قرار داده شده بدون پاس دادن اون متغیر مورد نظر.باید اون ها از Stage برداشته شه و با پاس دادن متغیر صحیح نمونه سازی و اضافه شه.
شما همه متد ها در کلاس ها رو public گرفتین که من اون هایی که نیازی نبود private کردم.
این فایل اصلاح شده به روشی که آقا جاوید گفتند.

من به روش خودم کار نکردم چون هموت طور که آقا هادی گفتند dispatch پروسه زیادی رو می گیره.

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

مثلا همین public static گرفتن متغیر یا متد تا وقتی واقعا بهش نیازی نباشه به نظر من منتقی نیست چرا که اصل encapsulation توی oop رو نقض می کنه.
شاید توی این مثال واقعا نیاز باشه اونم بر مبنای اینکه این متغیر رو باید کلیه کلاس هامون بهش دسترسی داشته باشند و بتونند تغییر بدند که باز هم بر می گرده به همون که اصلا ما قراره چی کار کنیم ...
از آقا هادی هم بابت راهنمایی که مطرح کردند ممنونم.
 

پیوست ها

  • bbb.rar
    9.2 کیلوبایت · بازدیدها: 6

(ehsan)

Member
نمیشه روی همون MovieClip هایی که روی Stage داریم کار کرد ؟ و بصورت run-time ادد نکرد ؟
 

clove-pink

کاربر فعال
نمیشه روی همون MovieClip هایی که روی Stage داریم کار کرد ؟ و بصورت run-time ادد نکرد ؟
برای اون کار من از دو تا کلاس دیگه استفاده کردم و در عوض پارامتری که به کلاس Circle پاس داده می شه رو برداشتم.
پیشنهادی که من دارم این هست که شما برنامه تون رو تجزیه کنید و ببینید کدوم روش واقعا مشکل رو حل می کنه.
 

پیوست ها

  • bbb.rar
    10.1 کیلوبایت · بازدیدها: 3

++Hadi++

Active Member
می شه همه کارا رو تو main انجام داد ولی تو یه سری شرایط بهتره هر کلاس وظایف خاص خودشو تو خودش انجام بده . معمولا من در این شرایط ، برا ارتباط بین اشیای ساخته شده از کلاسها ، از سیستم سراسری استفاده می کنم .
از clover pink عزیز هم تشکر می کنم .
 

(ehsan)

Member
متغیر سراسری که خیلی کارمو راه انداخت ، چون خیلی آسون بود . اما می آدم روشهای مختلف و خوب را هم یاد بگیره خیلی بهنره
 

جدیدترین ارسال ها

بالا