پاسخ به:کلاس اموزش برنامه نویسی اندروید(دوره اول)
جمعه 3 بهمن 1393 1:58 AM
مقدمه:
در قسمت قبل چند تعریف پایه ای از شیء گرایی مورد بررسی قرار گرفت، در این قسمت بحث پایه ای شیء گرایی را ادامه می دهیم. توجه کنید که این مباحث بسیار مهم است و آن چیزی که می نویسیم بیشتر شیء گرایی جاوا است تا اندروید.
آموزش:
در گذشته های نه چندان دور برنامه نویسی به این شکل بود که فایلهای خالی تشکیل می دادیم و دستورات را پشت سرهم می نوشتیم و اجرا می شد. در زمان حاضر برنامه نویسی به این شکل مگر در اسکریپ ها ( Scripting Languages * ) کاملاً غیر مرسوم و بلا استفاده است، بلکه ما از کلاسها برای نوشتن کدهای خود استفاده می کنیم که خواص بسیاری دارند و محدودیتهایشان هم سودمند است.
یکی از این تغییرات موجود در جاوا، ثابتها Constants * هستند، در هر کلاس مرتبط، میتوان const های خاص آن کلاس را تعریف کرد. در Java واژه const وجود ندارد. برای روشن شدن تعریف کدهای جلسه قبل را به شکل زیر تغییر دهید.
» کد مربوط به کلاس Vehicle.java را به شکل زیر تغییر دهید.
01 package com.uncocoder.course.lessons; 02 03 import android.util.Log; 04 05 public class Vehicle .. 06 07 public final static int TYPE_UNDEFINED = 0; 08 public final static int TYPE_CAR = 1; 09 public final static int TYPE_BOAT = 2; 10 public final static int TYPE_AIRPLANE = 3; 11 12 private final static String DEBUG_TAG = "LOG"; 13 14 public float mPositionX = 0; 15 public float mPositionY = 0; 16 public float mPositionZ = 0; 17 18 public int mWeight = 0; 19 public float mSpeed = 0; 20 21 private int mType = 0; 22 23 24 25 public Vehicle(float speed, int weight) .. 26 Log.i(DEBUG_TAG, "Vehicle Created with Speed: " + speed + ", Weight: " + weight); 27 mSpeed = speed; 28 mWeight = weight; 29 } 30 31 32 33 public void setType(int type) .. 34 if (type == TYPE_CAR) .. 35 Log.i(DEBUG_TAG, "Vehicle is Car"); 36 37 } else if (type == TYPE_BOAT) .. 38 Log.i(DEBUG_TAG, "Vehicle is Boat"); 39 40 } else if (type == TYPE_AIRPLANE) .. 41 Log.i(DEBUG_TAG, "Vehicle is Airplane"); 42 43 } else if (type == TYPE_UNDEFINED) .. 44 Log.i(DEBUG_TAG, "Type Undefined, Define a Valid Type"); 45 return; 46 47 } else .. 48 Log.i(DEBUG_TAG, "Use Const Values to Define a Type"); 49 return; 50 } 51 52 mType = type; 53 Log.i(DEBUG_TAG, "Vehicle Type Set!"); 54 } 55 56 57 58 public int getType() .. 59 Log.i(DEBUG_TAG, "Vehicle Type is: " + mType); 60 return mType; 61 } 62 63 64 65 public void turnOn() .. 66 Log.i(DEBUG_TAG, "Vehicle Turned On"); 67 } 68 69 70 71 public void turnOff() .. 72 Log.i(DEBUG_TAG, "Vehicle Turned Off"); 73 } 74 75 76 77 public void startMove() .. 78 Log.i(DEBUG_TAG, "Vehicle Starts Moving"); 79 } 80 }
خط 7 تا خط 10: چهار const از نوع int با مقادیر 0 تا 3 را با دید public تعریف کردیم، بنابراین از هر کلاسی قابل استفاده است.
خط 12: یک const از نوع String با مقدار "LOG" را با دید private تعریف کردیم، بنابراین فقط از داخل این کلاس قابل استفاده است.
خط های حاوی Log.i : با استفاده از ثابت DEBUG_LOG که مقدار "LOG" را دارد، log ها را چاپ می کنیم.
خط 34 تا 53: با استفاده از if..elseif...else مقادیر مختلف mType را چک کرده و پیغام مناسب را log می کنیم.
خط 45 و 49: با استفاده از return از ادامه متد منصرف می شویم بنابراین باقی خطوط بعد از این خط ها اجرا نخواهند شد.
همانطور که از کدهای بالا مشخص است یک const با استفاده از واژه static final تعریف می شود و به کمک visibility نوع دید سایرین به آن را تعیین می کنیم. برای نمایش مشخص تر const ها آنها را با حروف تماماً بزرگ نمایش داده و برای جدا کردن کلمات از _ استفاده کنیم.
» حال کد مربوط به متد initializeUi در کلاس AndroidCourseActivity.java را به شکل زیر تغییر دهید.
01 private void initializeUi() .. 02 btn = (Button) findViewById(R.id.btn_action); 03 text = (TextView) findViewById(R.id.txt_caption); 04 05 btn.setOnClickListener(new OnClickListener() .. 06 07 @Override 08 public void onClick(View v) .. 09 Vehicle myVehicle = new Vehicle(200f, 800); 10 myVehicle.turnOn(); 11 myVehicle.startMove(); 12 myVehicle.turnOff(); 13 14 myVehicle.mPositionX = 10; 15 myVehicle.setType(Vehicle.TYPE_CAR); 16 17 /* it's wrong code */ 18 //String str = Vehicle.DEBUG_TAG; 19 20 Log.i("LOG", "My Vehicle Type is: " + myVehicle.getType()); 21 } 22 }); 23 }
خط 15: با استفاده از ثابت TYPE_CAR مقدار mType را set می کنیم
خط 18: این مقدار خواندن نخواهد بود چرا که با توجه به تعریف آن در کلاس Vehicle از private visibility تبعیت می کند.
با توجه به مثال بالا می توانیم در مورد final و static بیشتر صحبت کنیم. به کلمات static, final, private, public, protected اصطلاحاً modifiers می گوییم.
Modifiers * :
static modifier :
با استفاده از آن باید به یک Field یا Method مستقیماً از طریق نام کلاس دسترسی پیدا کرد نه از طریق instance گرفته شده از کلاس یعنی می نویسیم Vehicle.TYPE_CAR و نمی نویسیم myVehicle.TYPE_CAR. با توجه به نوشته فوق مشخص است که حتی اگر instance ـی هم از آن کلاس نساخته باشیم، آن member ( فیلد یا متد ) قابل استفاده خواهد بود. این موضوع در جاهای متفاوتی به ما کمک می کند. فرض کنید که می خواهیم تعداد Vehicle های ساخته شده را در جایی ذخیره کنیم، دقیقا مانند این که بخواهیم بگوییم « از این نوع وسیله نقلیه چند تا داریم ». برای بیان جمله قبل نیازی به ساخت حتی یک نمون وسیله نقلیه هم نیست. بنابراین می توانیم در کلاس Vehicle بنویسیم:
01 public static int mVehicleCount = 0;
و برای تغییر آن ( اضافه کردن به آن ) می توانیم به صورت زیر ( مثلا در متد initializeUi ) بنویسیم:
01 Vehicle.mVehicleCount++;
اگر از static قبل از نام متد استفاده کنیم، همانطور که می توانستیم به فیلد را مستقیماً از نام کلاس دسترسی داشته باشیم، می تواینم به متد هم مستقیم دسترسی داشته باشیم، این موضوع هم شبیه این است که بگوییم « این نوع وسیله نقلیه چگونه سوخت گیری می کند »، برای بیان عبارت قبل هم نیازی به ساخت یک نمونه از وسیله نقلیه ندارم.
اینگونه متدهای استاتیک معمولاً Helper نامیده می شوند و کاربردهای مستقل از instance دارند. بطور مثال ممکن است متدی بخواهیم که یک عدد تصادفی تولید کند. می توان این متد را داخل کلاسی به نام MathHelpers تعریف کرد و هر جای دیگر با دستور MathHelper.getRandom آنرا فراخواند.
final modifier :
با استفاده از آن می توان به java compiler و eclipse فهماند که این member ( فیلد یا متد ) پس از تعریف اولیه مجدداً قابل تعریف نیست.
اگر این modifier قبل از نام فیلد استفاده شود به معنی این است که فیلد قابل مقداردهی مجدد نیست پس در همان خط باید مقدار دهی شود.
اگر قبل از نام پارامتر استفاده شود به معنی این است که نمی توان پارامتر را دوباره تغییر داد و فقط به منظور خوانده شدن استفاده می شود.
اگر قبل از نام متد استفاده شود به معنی این است که نمی توان متد را Override ( که بعداً توضیح می دهیم ) کرد.
اگر قبل از نام کلاس استفاده شود به معنی آن است که نمی توان از کلاس، subclass ـی تهیه کرد.
اگر به همراه static قبل از نام فیلد بکار رود به معنی تعریف یک ثابت است.
بنابراین بیشتر کاربرد final برای امنیت و کم کردن خطای برنامه نویس ( برنامه نویسان ) است.
private modifier :
مورد استفاده شده فقط در داخل کلاس قابل دید است و خارج از کلاس قابل دیدن نیست. این موضوع عملیات داخل کلاس را که معمولاً خیلی شلوغ و پر متغیر است را به بیرون انتقال نداده و باعث تمیز شدن کد و راحتی استفاده از کلاس می گردد.
protected modifier :
مورد استفاده شده فقط در داخل کلاس و زیر کلاسهای آن قابل دید است و خارج از آنها قابل دید نیست. این موضوع هم به تمیز بودن کد کمک شایانی می کند.
public modifier :
مورد استفاده شده در همه کلاسها قابل دید است. توصیه می شود از این modifier در مکان صحیح استفاده کنید و اگر واقعاً دید در همه کلاسها لازم نیست از آن استفاده نکنید.
default modifier :
اگر هیچ کدام از private, protected, public قبل از نام فیلد یا متد استفاده نشود از default modifier استفاده شده است و معنی آن اینست که مورد استفاده فقط در کلاسهایی قابل دید است که در یک package قرار داشته باشند. این modifier هم برای نوشتن module ها بسیار کاربرد دارد. جدول زیر نمای واضحتری را نشان می دهد.
مفهوم this:
همانطور که در بحث کلاس اشاره شد، برای دسترسی به متدها و فیلدهای غیر استاتیک یک کلاس نیاز به ساخت یک نمونه ( instance ) از آن کلاس داریم. با استفاده از این instance و operator نقطه ( . ) می توانیم به متدها و فیلدهای public ( و بعضاً protected ) دسترسی پیدا کنیم. حال عبارت this چه کمکی به ما می کند. اگر داخل متدهای غیر استاتیک از کلمه this استفاده شود به آن instance ـی که این متد را فراخوانی کرده اشاره می کند، پس می توانیم آنرا به سایر متدها بصورت یک پارامتر از جنس همان کلاس انتقال دهیم. انتقال دادن آن به سایر متدهای غیر استاتیک آن کلاس کار بیهوده ای است چون آنجا هم خود this معنی دارد، اما انتقال دادن آن به متدهای استاتیک همان کلاس و مخصوصاً به متدهای استاتیک و یا غیراستاتیک سایر کلاسها کاملاً مرسوم و کاربردی است.
» کد زیر را به کلاس Vehicle.java بعد از startMove اضافه کنید:
01 public void sendNetworkData() .. 02 Log.i(DEBUG_TAG, "Vehicle Networking"); 03 NetworkManager.sendVehicle(this); 04 }
» همینطور کلاس NetworkManager زیر را به نحوی که قبلاً گفته شده در com.uncocoder.course.lessons بوجود آورید و آنرا به شکل زیر edit کنید:
01 package com.uncocoder.course.lessons; 02 03 public class NetworkManager .. 04 05 public static void sendVehicle(Vehicle vehicle) .. 06 if (vehicle != null) .. 07 /* do some action with vehicle data 08 * and send it through network 09 */ 10 } 11 } 12 }
با دیدن دو کد بالا می توان مفهوم this را به خوبی درک کرد.
سورس برنامه:
می توانید سورس را از آدرس زیر دانلود کنید:
توصیه ها:
- اگر با مفاهیم شیء گرایی ( Object Oriented * ) آشنایی لازم را ندارید بهتر است کتابی در مورد java تهیه و مطالعه کنید، با اینکه در این آموزشها با آن خواهیم پرداخت، اما مطالعه شما بهتر است.
- با همین مفاهیم اولیه در مورد شیء گرایی بسیار تمرین کنید و خود را در این مفاهیم قوی کنید تا در آموزشهای آتی بسیار راحتتر عمل کنید.
Android , iOS , Windowsphone , Symbian , Java, Mobile Review ,Learning