مفاهیم شی گرایی
با نام و یاد خدا
در جلسات قبل به نصب JDK، SDK و Android Studio پرداختیم. قبل از ورود به بحث کدنویسی در محیط اندروید استودیو لازم است که به بحث مهم شی گرایی در جاوا بپردازیم. شی گرایی یکی از مهمترین مسئله هایی است که هر برنامه نویسی باید با آن آشنا باشد. کاربرد مفاهیم شی گرایی در جاوا را در جلسات بعد در حین برنامه نویسی در محیط اندروید خواهیم دید. (مفاهیم شی گرایی در زبان سی شارپ به صورت مختصر قبلا گفته شد.)
شی گرایی چیست؟
یک شیوه برنامه نویسی است که ساختار اصلی اجزای آن، شی می باشد. استفاده از این شیوه برنامه نویسی باعث سازماندهی کدها می شود.
دلیل مطرح شدن شی گرایی در حوزه برنامه نویسی چیست؟ نحوه عملکرد مغز و شیوه دریافت اطلاعات از محیط پیرامون و پردازش آن اطلاعات، شیوه شی گراست. به همین دلیل می بایست زبانی تعریف شود که همین شیوه را مبنای کار خود قرار داده و باز تولید کند.
مفاهیم شی گرایی در جاوا
مفاهیم شی گرایی در تمام زبان ها یکسان است ولی نحوه کاربرد آنها ممکن است متفاوت باشد. این مفاهیم شامل موارد زیر می باشد:
- کلاس(Class)
- شی(Object)
- صفت(Attribute)
- رفتار(Behavior)
- ارث بری(Inheritance)
- چندریختی(Polymorphism)
- کپسوله سازی(Encapsulation)
- انتزاع یا تجرید (Abstraction)
در ادامه به شرح تک تک مفاهیم شی گرایی در جاوا می پردازیم و از مثال خودرو (car) برای درک کامل مفاهیم استفاده می کنیم.
-
کلاس(Class):
کلاس یک الگویی است که ما تعریف می کنیم که بتوانیم بر اساس آن یک Object را ایجاد کنیم.
-
شی(Object):
اگر به عالم واقعیت نگاه کنید در عالمی زندگی می کنید پر از اشیا، مثل ماشین ،صندلی،چتر یا هر چیز دیگری که در دنیای واقعی می بینید یک شی است.
شی(Object) نمونه هایی است که از روی کلاس می سازیم.
-
صفت(Attribute):
یک خودرو رنگ دارد ،کمربند دارد ،تعدادی لاستیک دارد ،موتور دارد و الی آخر که به این ویژگی ها صفت می گویند.
-
رفتار(Behavior):
همین ماشین می تواند حرکت کند، سرعت بگیرد، ترمز کند، خاموش شود و الی آخر که به آن رفتار یا متد می گویند.
اجزای تشکیل دهنده یک کلاس
کلاس از دو جزء تشکیل شده است:
- Variables یا متغیرها
- Methods یا رفتارها
- انواع متغیرها
- Class variables: به زبان ساده متغیرهایی که فقط به درد همین کلاس می خورد و ربطی به خود شی پیدا نمی کند و در داخل متدها نیز قابل تعریف شدن نیست و مشخصه ی آن کلمه کلیدی static می باشد.
- Local variables:متغیرهایی که داخل متدها تعریف می شوند.
- Instance variables : متغیرهایی که متعلق به یک نمونه از کلاس هستند.
جایگاه این اجزا را داخل کلاس خودرو مشخص می کنیم:
class Car
{
//class variable
private static int status = 1;
//instance variable
private int currentspeed = 20;
public Car()
{
}
private void Driving()
{
//local variable
Boolean isDriving = false;
}
}
- انواع متدها
متد سازنده(constructor): متدی است که به محضی که از روی کلاس شی ساخته شد اجرا می شود و باید هم نام با نام کلاس باشد.
class Car
{
//class variable
private static int status = 1;
//instance variable
private int currentspeed = 20;
//متد سازنده
public Car()
{
}
private void Driving()
{
//local variable
Boolean isDriving = false;
}
}
نکته:یک کلاس می تواند چندین متد سازنده داشته باشد ولی به چند شرط (با استفاده از مفهوم overloading)
مفهوم Overloading:
اگر یک تابع چندین بار با یک نام ولی با آرگومان های مختلف پیاده سازی شود Overloading گفته می شود.
public Car()
{
}
//تابع با یک آرگومان
public Car(string name)
{
}
//تابع با دو آرگومان
public Car(int id,string name)
{
}
ساختن یک object
مراحل ساخت شی از روی کلاس به ترتیب شامل موارد زیر می باشد:
- ابتدا نوشتن نام کلاس
- تعریف متغیر برای شی
- استفاده از کلمه ی new برای ساخت شی جدید
- فراخوانی متد سازنده بعد از کلمه ی new
Car car = new Car();
Car car = new Car(“benz“);
-
ارث بری (Inheritance)
ارث بری یعنی چه؟ یکی از مسائل مهم در شی گرایی در جاوا بحث ارث بری است. اگر در عالم واقعیت هم نگاه کنیم مفهوم ارث بری را به وضوح می بینیم، مثال : در دنیای واقعی ممکن است یک سری خصوصیات و یا رفتارها را از پدرمان به ارث ببریم مثل شکل ظاهری، رفتار،اموال و …..
مثال خودروها:
ما یک کلاس خودرو داشتیم بنام کلاس Car ،کلاس های دیگری را ایجاد می کنیم بنام کلاس benz ، bmv، prid که از کلاس Car ارث بری کرده اند .
کلاس Benz که از کلاس Car ارث بری کرده و می گوید علاوه بر چیزهایی که کلاس پدرم دارد من GPS هم می خواهم اضافه تر داشته باشم.
نکته: وقتی بخواهیم که یک کلاس از کلاس دیگری ارث بری کند از کلمه ی extends استفاده می کنیم.
public class Benz extends Car
{
private int gpsstatus;
public Benz()
{
}
}
Superclass:به کلاس Car که کلاس بزرگتر ی است می گویند. Superclass در واقع همان کلاس پدر است.
Subclass: کلاس Benz که از کلاس Car ارث بری می کند به آن Subclass می گویند .در واقع همان کلاس فرزند است.
-
Overriding
پیاده سازی یک رفتار به ارث برده از superclass و تغییر آن بر اساس نیازهای خود را overriding گویند.
Overriding یعنی دوباره نوشتن؛ به زبان ساده درسته که یک چیزی را از پدرم به ارث بردم ولی مطابق میل خودم عوضش کردم البته اگر سطح دسترسی به ما اجازه دهد که این مبحث هم در مطالب بعدی بیان می کنیم.
نمونه آن ، کلاس بنز(Benz) که از کلاس Car ارث برده است و همچنین Override کرده است.
یک تابعی قبلا داخل کلاس superclass بوده است بنام drive و brak ؛ که کلاس بنز آن ها را Override کرده است و بعد گفته super.drive یعنی من نمی خواهم این تابع را دستکاری کنم هر چیزی که برای پدرم هست به من هم برسد (البته می توانیم دستکاری کنیم و تغییر دهیم )
public class Benz extends car
{
private int gpsStatus;
public Benz()
{
}
@override
public void drive()
{
super.drive();
}
@override
public void brak()
{
super. brak ();
}
}
-
قوانین مهم override
1- لیست آرگومان های تابع دقیقا، همان تعدا آرگومان های تابع override شده باشد. یعنی اگر قرار است تابع را دستکاری کنید باید ببینید تابع چند تا ورودی داشته است همان را استفاده کنید و فقط می توانید دستوراتش را عوض کنید ولی نمی توانید دست به ورودی و خروجی آن بزنید.
2- Return type تابع دقیقا همان Return type تابع override شده باشد. یعنی اگر نوع برگشتی تابع از نوع int بود اینجا هم باید از نوع int در نظر بگیریم.
3- تابعی که Final تعریف شده باشد،قابل override شدن نیست. یعنی اگر اول تابع کلمه ی Final بود کسی حق دستکاری داخل این تابع را ندارد.
4- تابعی که Static تعریف شده باشد، قابل override شدن نیست ولی قابل دوباره تعریف کردن است.
5- Constructor ها قابل override شدن نیست.
-
کپسوله سازی(Encapsulation)
جدا سازی Variable های یک کلاس از دید سایر کلاس ها(Data Hiding) را کپسوله سازی گویند.
موارد مورد نیاز برای دستیابی Encapsulation:
- استفاده از سطح دسترسی Private برای تعریف کردن متغیرهای کلاس
- نوشتن Getter و Setter برای دسترسی به Variable ها
به زبا ساده کپسوله سازی یعنی چیزی که از بیرون به آن دسترسی نداریم، برای مثال یک تلویزیون را در نظر می گیریم. آیا سازنده تلویزیون صفحه پشت تلویزیون را باز نگه می دارد و به مشتری می گوید که این مدارات و آی سی ها چنین کارهایی را انجام می دهد ؟ و برای اینکه مثلا صدا را کم یا زیاد کنی این دو سیم را به هم وصل کن؟ نه سازنده تلویزیون یک پکیجی را به صورت کنترل تلویزیون آماده می کند و می گوید که بوسیله این کنترل می توانید چه کارهایی را انجام دهید و مثلا برای کم کردن صدا این دکمه را فشار دهید.
با استفاده از تابع Getter متغیرها را از کاربر یا مشتری می گیرد و با استفاده از تابع Setter یک عملیاتی را انجام می دهد:
public class EncapuslationExample
{
private int id;
private string firstName;
private string lastName;
private string email;
public int getId()
{
return id;
}
public void setId(int id)
{
this.id = id;
}
public string getFirstName()
{
return firstName;
}
public void setFirstName(string firstName)
{
this.firstName = firstName;
}
}
- مزایای Encapsulation
- قابلیت Read only یا Write only کردن متغیرهای کلاس .
- کنترل کامل داشتن کلاس روی اینکه چه دیتایی داخل متغیرهایش ذخیره شود.
- شخصی که از کلاس استفاده می کند، اصلا نمی داند چطور دیتا داخل کلاس ذخیره می شود. مثلا اگر نویسنده کلاس تصمیم بگیرد نوع متغیر را عوض کند،کسی که از کلاس او استفاده می کرده،نیازی به تغییر کد ندارد.
-
انتزاع یا تجرید(Abstraction)
پیاده سازی نکردن جزییات و فقط مشخص کردن عملکردهای کلاس را Abstraction می گویند.
- چه زمانی از abstraction استفاده می کنیم؟ زمانی که می دانیم چه کارهایی باید انجام شود اما نمی دانیم چطوری باید انجام شود!
برای مثال می دانیم که یک قسمت از برنامه ما مربوط به تاکسی تلفنی ها است اما نمی دانیم که چگونه باید این کلاس را پیاده سازی کنیم، پس در اینجا یک کلاس Abstraction تشکیل می دهیم.
public abstract class Abstractcar
{
private string name;
abstract void driving();
abstract void stop();
private string getName()
{
return name();
}
private void setName(string name)
{
this.name = name;
}
}
- چطور از کلاس Abstract شی بسازیم؟قبلا روش ایجاد شی را برای شما توضیح دادیم ولی ایجاد شی برای کلاس Abstract فرق دارد.
public class Bmv extends Abstractcar
{
@override
void driving()
{
}
@override
void stop()
{
}
}
-
Interface
Interface شبیه کلاسی است که فقط شامل Abstract Metod باشد.
در دنیای واقعی یک چیز فقط می تواند رفتار یک چیز دیگری را داشته باشد مثلا انسان نمی تواند هیچ موقع گربه باشد ولی می تواند مانند گربه چهار دست و پا راه برود.
public interface interfaceExample
{
abstract void doThis();
abstract void doThat();
}
- چگونگی استفاده از Interface
public class EncapuslationExample implements interfaceExample
-
چند ریختی Polymorphism
قابلیتی که یک شی می تواند اشکال مختلفی به خود بگیرد .در مثال زیر یک شی به نام benz داریم که از کلاس Car و Vehicle و Object ارث بری می کند. در مثال زیر benz می تواند از Vehicle ارث بری کند چون benz از Car ارث بری کرده بود و کلاس Car هم از Vehicle .
public class Vehicle extends Object
public class Car extends Vehicle
public class Benz extends Car
polymorphism //
Benz benz =new Benz ();
Car car = benz;
Vehicle vehicle = benz;
Object object = benz;
خب مفاهیم شی گرایی در جاوا اینجا به پایان رسید. در ادامه یک توضیح مختصری درباره ساختار کدنویسی در جاوا می دهیم تا برای ادامه کار و برنامه نویسی در اندروید استودیو راحت تر باشید.
ساختار کد نویسی در جاوا
- حساسیت به حروف کوچک و بزرگ (Case Sesentive) مثال : hello و Hello با هم تفاوت دارند.
- نام کلاس ها باید با حرف اول بزرگ شروع شوند. مثال:MainClass
- نام متدها باید با حرف اول کوچک شروع شوند . مثال :()doThat
- نام فایلی که ذخیره می کنیم حتما باید هم نام کلاس باشد.
قواعد نام گذاری Identifiers
- حتما باید با یکی از حروف الفبای انگلیسی (A to Z) یا علامت $ یا _ شروع شوند.
- بعد از اوین حرف، هر ترکیبی از کاراکترها را می توان استفاده کرد.
- بعدKeyword نمی تواند به عنوان Identifier استفاده شود.
- Identifier به حروف کوچک و بزرگ حساس هستند .
مثال
نام گذاری صحیح: age,$salary,_value,_1
نام گذاری اشتباه: 123abc,-salary
مفهوم پکیج () در جاوا
در جاوا برای جلوگیری از تداخل در اسامی کلاس ها ،اینترفیس ها و جستجوی راحت بین آن ها و همچنین جلوگیری غیر مجاز، از مفهوم پکیج استفاده می شود . که در جلسات بعد در اندروید استودیو خواهیم دید.
Modifiers
- به کلماتی گفته می شود که می توانند وضعیت و نوع کلاس ها ، متدها و غیره را عوض کنند.
- Access modifiers :برای تعیین سطح دسترسی مورد استفاده قرار می گیرند.
public,private,protected,default
- Non- Access modifiers :برای کارهایی غیر تعیین سطح دسترسی مورد استفاده قرار می گیرد.
final,abstract,static
- Access modifiers
- private :فقط در کلاس خود قابل دیدن هستند.
- public :در همه جا قابل دیدن هستند.
- protected :فقط برای پکیج خود و تمامی Subclass ها دیدن هستند.
- default :برای پکیج فقط قابل دیدن هستند.
- Non Access modifiers
static : برای تعریف Class method و Class variable مورد استفاده قرار می گیرد.
final : زمانی استفاده می شود که دیگر نمی خواهیم به متغیری اجازه تغییر دهیم
abstract : برای تعریف کلاس یا متد Abstract به کار می رود .
تعریف کلاس در جاوا
public class Student
{
//Class variable
public static int MAXIMUM_SCORS = 20;
//Instance variable
private string name;
private string LastName;
private string getFullName()
{
//Local variable
string fullName = name + LastName;
return fullName;
}
}
شما می توانید در آدرس سایت زیر تمام آموخته های خود در برنامه نویسی به زبان جاوا را به صورت آنلاین تست کنید و مفاهیم شی گرایی در جاوا و ساختار کدنویسی جاوا را بیشتر درک کنید:
http://www.tutorialspoint.com/compile_java8_online.php
تا اینجا مفاهیم شی گرایی در جاوا و همچنین یک سری توضیحات درباره ساختار کدنویسی در جاوا را گفتیم. امیدواریم شی گرایی در جاوا را به خوبی یاد گرفته باشید. در جلسات بعد کاربرد شی گرایی در جاوا را خواهید دید. با ما همراه باشید.
سلام …لطفا اگر ممکنه از ارث بری به بعد رو بصوری یه کلیپ در بیارین که متوجه شیم
سلام من فیلمهای آموزشی زبان جاوا رو دیده بودم برای ساخت اندروید.ولی دوره کردنش برام کابوس بود. با مطالب شما خیلی خوب برام مرور شد. خدا خیرتون بده
با سلام و سپاس فراوان بابت آموزش بسیار جالب اندروید که در بسیاری از سایتها همین آموزش ها فروخته می شود و به رایگان فابل دسترسی نیست
من تازه شروع کردم به برنامه نویسی و از مطالب شما استفاده میکنم
تشکر
قرار دادن این مبحث بصورت بصورت رایگان، قابل ستایش و تقدیره. امیدوارم موفق و پیروز باشید.
سلام
با تشکر از آموزش رایگان شما
سپاس فراوان
با عرض سلام
خود من شخصا چند ماه درگیر پکیج های آموزشی هستم هم به صورت رایگان و هم به صورت پولی ولی این پکیج آموزشی شما فوقالعاده بود
اگر شماره کارت اعلام کنید خود من حداقل به اندازه هزینه پکیج های دیگه ایی که قرار بود بکنم و فقط بیشتر سردرگم بشم قطعا با رضایت کامل واریز میکنم .البته اگر پولی به احتمال خریدش برای من خیلی کم بود چون نمیدونستم چه محتوایی داره وای الان قطعا با یک مبلغ معقول زحمتتون به نسبت خودم جبران میکنم
بازهم متشکرم
سلام و عرض ادب
رضایت شما و سایر کاربران، موجب دلگرمی اعضای تیم ماست. الویت اول تیم داژیار ، کمک به مخاطبان در جهت رشد و یادگیری در حوزه تکنولوژی می باشد .شما می توانید از طریق منوهای بالای سایت اقدام به ثبت نام در سایت و خرید عضویت ویژه کنید و استفاده از تمام مقالات روی سایت باشید. البته درآمد عضویت ویژه برای ادامه حیات این سایت ضروری بوده است.
با تشکر از همراهی شما
عزیز تو قسمت non access modifier , abstract و final رو جابه جا گذاشتی
با سلام. بسیار عالی بود. من تازه میخوام با مفاهیم شی گرایی و برنامه نویسی برای اندروید آشنا بشم. مطالب زیادی رو اخیرا خواندم ولی مطالبی که شما مطرح کردید بسیار دسته بندی شده و قابل فهم بود. ممنون از شما. موفق باشید
سلام و عرض ادب. از ارسال نظر شما ممنون هستیم.
با تشکر از همراهی شما
سلام خیلی ممنون بابت توضیحات خوبتون فقط اون قسمت return getName(); در قسمت آبستره کردن، نباید return Name; باشه؟ ( در تابع getter )
سلام و عرض ادب. بله اشتباه تایپی بود و اصلاح شد.
باتشکر از همراهی شما
هیچکس مثل شما خوب توضیح نداده بود دمتون گرم
سلام
بابت مقاله خیلی خوبتون ممنون. و خداقوت. فقط یه نکته: در جایی که بحث overloading رو مطرح کردید، نوشتید که وقتی چند تابع با نام یکسان ولی با آرگومان های مختلف پیاده سازی بشن به این میگن Overloading (یا همون سربارگزاری متد). نکته ظریفی که هست تفاوت واژه ها و اصطلاحات “آرگومان” و “پارامتر” هست. درواقع بهتر بود بجای واژه آرگومان از پارامتر استفاده میکردید.
چراکه “آرگومان” به مقادیری گفته میشه که هنگام فراخوانی تابع بهش پاس میدیم. و “پارامتر” ورودی های تابع هنگام تعریف تابع هستند.
اون قسمت آخر ، فک میکنم تعریف فاینال و ابسترکت جابجا شده درستش کنین.
سلام و عرض ادب. پست ویرایش شد.
با تشکر از همراهی شما
ممنون از این مقاله کاربردی
سلام و عرض ادب
رضایت شما موجب خرسندی ماست و حمایت شما برای ما بسیار ارزشمند است.
با تشکر از همراهی شما