با استفاده از ویژگی شی گرایی در برنامه نویسی راحت تر میتونید به توسعه ی اپ های بزرگ و رابط گرافیکی کاربری بپردازید.
جاوا یک زبان کاملا شی گراست و کد های جاوا به سبب ویژگی شی گرایی این زبان توسعه داده میشن.
معمولا آبجکت یک ماهیت از دنیای واقعی رو شبیه سازی میکنه مثلا یک دانش آموز، یک تلویزیون، یک دایره ، یک مستطیل و هر شی تو دنیای واقعی میتونه با یک آبجکت (object) شبیه سازی بشه.
به نمونه هایی که از یک کلاس ایجاد میکنیم؛ آبجکت میگیم.
به آبجکت ها، اشیا نیز گفته میشه اما کلمه ی آبجکت شناخته شده تر است.
هر آبجکت از کلاس اطلاعات مختص به خودشو داره.
StringBuilder sb0 = new StringBuilder("This is information of the first Object");
StringBuilder sb1 = new StringBuilder("This is information of the second Object");
System.out.println(sb0);
System.out.println(sb1);
آبجکت ها مستقیم در حافظه ایجاد میشن و متغیر های آبجکتی، بهجای آبجکت، آدرس آبجکت رو در خودشون ذخیره میکنن و توسط آدرس به آبجکت ایجاد شده در حافظه اشاره میکنن.
StringBuilder sb = new StringBuilder("Hello StringBuilder!");
در بالا متغیر sb اشاره به آبجکت ایجاد شده ی StringBuilder در حافظه داره.
ساختار کلاس در جاوا
آبجکت از روی کلاس ایجاد میشه.
یک کلاس رو در جاوا با کلیدواژه ی سطح دسترسی، کلیدواژه ی class، اسم کلاس و بدنه ی کلاس تعریف میکنیم.
فرم کلی:
public class Name{
...
}
به طور کلی داخل یک کلاس در جاوا سه بخش مهم داریم که تصویر زیر نمایانگر این سه بخش است.
ساختار یک کلاس در جاوا
1- دیتا فیلد
به متغیر های داخل کلاس در جاوا دیتا فیلد (data field) میگیم. داده های آبجکت در دیتافیلد ها ذخیره میشن. به داده های کلاس ویژگی (attribute) های کلاس هم میگیم.
2- کانستراکتور (constructor)
با کانستراکتور در جاوا یک آبجکت (نمونه) از کلاس ایجاد میکنیم. میتونیم برای یک کلاس در جاوا یک یا چند کانستراکتور تعریف کنیم.
در تصویر t0, t1, ..., tn پارامتر های کانستراکتور هستند.
3- متد (method) ها
متد های کلاس نیز مانند متغیر های کلاس (دیتا فیلد) میتونن وابسته به آبجکت یا استاتیک باشن. میتونیم یک یا چند متد داخل یک کلاس جاوا تعریف کنیم.
دیتا فیلد (data field) ها
اطلاعات آبجکت در دیتافیلد ها ذخیره میشه. به دیتافیلد ها، پراپرتی (property) هم میگیم.
به متغیر هایی که داخل کلاس تعریف میکنیم دیتافیلد (data field) یا به اختصار فیلد میگیم.
به طور کلی دو نوع فیلد استاتیک و غیر استاتیک (member) میتونیم داخل یک کلاس تعریف کنیم.
فیلد های غیر استاتیک اطلاعات آبجکت رو در خودشون ذخیره میکنن.
به فیلد های غیر استاتیک، فیلد های عضو (member) هم میگن.
داخل کلاس میتونیم یک یا چند فیلد تعریف کنیم.
تعریف فیلد در کلاس
به صورت زیر فیلد ها رو داخل کلاس تعریف میکنیم:
public class MyClass{
String myField = "This is a field";
}
اگه به فیلد مقدار اولیه ندیم؛ مقدار پیشفرض در صورتی که نوع فیلد boolean باشه false، عددی باشه 0 و آبجکت باشه null است.
public class Rectangle{
//width = null
double width;
//height = null
double height;
}
میتونیم با گذاشتن نقطه بعد از اسم متغیر آبجکتی، فیلد موردنظر رو صدا بزنیم.
سطح دسترسی یک فیلد میتونه private, public, protected یا default باشه.
استفاده از کلیدواژه ی this برای فیلد ها
اگه یک فیلد رو بخوایم داخل کلاس خودش صدا بزنیم و اسم فیلد با اسم پارامتر یا متغیر های داخل متد یکی باشه، با this مشخص میکنیم متغیری که داریم صدا میزنیم مربوط به فیلد است.
public class Rectangle{
double width;
private double height;
public void setWidth(double width){
this.width = width;
}
public void setHeight(double height){
this.height = height;
}
}
کانستراکتور (سازنده)
کانستراکتور در جاوا، نوع خاصی از متد است که هیچ مقداری رو برنمیگردونه و با صدا زدن کانستراکتور یک نمونه از کلاس ایجاد میکنیم.
با استفاده از کانستراکتور (constructor) در جاوا میتونیم یک آبجکت از کلاس ایجاد کنیم.
داده های هر آبجکت مختص به خودشه و در فیلد ها ذخیره میشن.
تمام کلاس های جاوا یک کانستراکتور پیشفرض پنهانی دارند یعنی اگه برای کلاس کانستراکتور تعریف نکنیم، کانستراکتور زیر به صورت پیشفرض وجود داره:
public class MyClass{
public MyClass(){
}
}
سطح دسترسی کانستراکتور های یک کلاس میتونه public, private, protected یا default باشه.
public class MyClass{
private MyClass(){
...
}
}
میتونیم یک یا چند کانستراکتور برای کلاس تعریف کنیم. همچنین از طریق پارامتر های کانستراکتور میتونیم فیلد های کلاس رو مقداردهی کنیم.
public class Rectangle{
Date dateCreated = new Date();
double width;
double height;
String color = "White";
public Rectangle(double width, double height, String color){
this.width = width;
this.height = height;
this.color = color;
}
}
اگه یک کانستراکتور به صورت آشکار تعریف کرده باشیم دیگه کانستراکتور پیشفرض وجود نداره و در صورت نیاز باید کانستراکتور پیشفرض رو به طور آشکار تعریف کنیم.
public class Rectangle{
Date dateCreated = new Date();
double width;
double height;
String color;
public Rectangle(double width, double height, String color){
this.width = width;
this.height = height;
this.color = color;
}
public Rectangle(){
}
}
استفاده از کلیدواژه ی this برای کانستراکتور.
میتونیم با کلیدواژه ی this در کلاس یک کانستراکتور رو داخل کانستراکتور دیگه صدا بزنیم.
public class Rectangle{
Date dateCreated = new Date();
double width;
double height;
String color;
public Rectangle(double width, double height, String color){
this.width = width;
this.height = height;
this.color = color;
}
public Rectangle(){
this(1.0, 1.0, "White");
}
}
ایجاد نمونه از کلاس
با استفاده از کلیدواژه ی new و صدا زدن یکی از کانستراکتور های کلاس میتونیم یک نمونه (آبجکت) از کلاس ایجاد کنیم.
مثال
در زیر دو نمونه (آبجکت) از کلاس Rectangle ایجاد کردیم. نمونه ی اولی با کانستراکتور بدون پارامتر ایجاد شده و نمونه ی دوم با کانستراکتور پارامتر دار.
در بخشمتد ها در جاوا به طور مفصل به این موضوع پرداختیم برای مطالعه در باره ی متد ها میتونید به این بخش مراجعه کنید.
مفهوم کپسوله سازی
برای جلوگیری از دسترسی به فیلد توسط کلاس های دیگه در خارج از کلاس میتونیم با private تعریفش کنیم. به این کار کپسوله سازی دیتا فیلد میگیم.
اگه بخوایم به دیتافیلد کپسوله شده در خارج از کلاس دسترسی داشته باشیم، برای دسترسی به فیلد باید متد getter و برای تغییر در مقدار فیلد باید متد setter رو تعریف کنیم.
متد های getter و setter، متد های قراردادی هستند که توسط برنامه نویس ها شناخته شده اند. متناسب با اسم فیلد به صورت getMyField و setMyField تعریفشون میکنیم.
public class Rectangle {
private Date dateCreated =new Date();
private double width;
private double height;
private String color;
public Rectangle(double width , double height){
setWidth(width);
setHeight(height);
}
public Rectangle(){
this(1d, 1d, "White");
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public void setWidth(double width) {
this.width = width;
}
public double getWidth() {
return width;
}
public void setColor(String color) {
this.color = color;
}
public String getColor() {
return color;
}
public Date getDateCreated() {
return dateCreated;
}
}
مقدار null در جاوا
فیلد های کلاس اگه مقداردهی نشن به طور پیشفرض به null اشاره میکنن.
کلمه ی null یعنی تهی؛ اگه از متغیر هایی که به null اشاره میکنن استفاده کنیم، زمان اجرای برنامه دچار NullPointerException میشه.
از کلیدواژه ی null زمانی استفاده میکنیم که در ابتدا قصد استفاده از متغیر رو نداشته باشیم و بعدا در برنامه بخوایم با متغیر به یک آبجکت اشاره کرده و ازش استفاده کنیم.
، اگه یک متغیر آبجکتی نه به null اشاره کنه و نه مقداردهی شده باشه در پروژه دچار خطای کامپایل میشیم.
public R myMethod(...){
Scanner input;
//خطای کامپایل
String name = input.next();
}
اگه با متغیر به null اشاره کرده باشیم زمان اجرای برنامه دچار NullPointerException میشیم.
public R myMethod(...){
Scanner input = null;
//خطای زمان اجرا
String name = input.next();
}
یکی از دلایل مطرح شدن مقدار null در جاوا قابلیت استفاده از متغیر بدون نیاز به مقداردهی در بررسی شرط ها است.
متغیری که مقداردهی نشده باشه رو نمیتونیم در شرط بررسی کنیم ولی متغیر هایی که به null اشاره میکنن در شرط ها قابل بررسی هستند.
public R myMethod(...){
MyObject myObject = null;
while(myObject == null){
//Do some stuffs
...
}
}
مورد مطالعه (مثال ها)
وقتشه کلاس مستطیل (Rectangle) رو کامل کنیم.
public class Rectangle {
private Date dateCreated = new Date();
private double width;
private double height;
private String color;
public Rectangle(double width , double height, String color){
setWidth(width);
setHeight(height);
setColor(color);
}
public Rectangle(){
this(1d, 1d, "White");
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public void setWidth(double width) {
this.width = width;
}
public double getWidth() {
return width;
}
public void setColor(String color) {
this.color = color;
}
public String getColor() {
return color;
}
public Date getDateCreated() {
return dateCreated;
}
public double getArea(){
return width * height;
}
public double getPerimeter(){
return 2 * (width + height);
}
}
استفاده از کلاس Rectangle در متد main.
public class Main{
public static void main(String[] args){
Rectangle rect0 = new Rectangle();
System.out.println("New rectangle created on " + rect0.getDateCreated());
System.out.println("Width: " + rect0.getWidth() + "Height: " + rect0.getHeight());
System.out.println("Area: " + rect0.getArea());
System.out.println("Perimeter: " + rect0.getPerimeter());
System.out.println();
Rectangle rect1 = new Rectangle();
System.out.println("New rectangle created on " + rect1.getDateCreated());
System.out.println("Width: " + rect1.getWidth() + "Height: " + rect1.getHeight());
System.out.println("Area: " + rect1.getArea());
System.out.println("Perimeter: " + rect1.getPerimeter());
}
}
مثال
تعریف کلاس Circle.
public class Circle {
private Date dateCreated = new Date();
private double radius;
private String color;
public Circle(double radius, String color){
this.radius = radius;
this.color = color;
}
public Circle(){
this(1.0, "White");
}
public void setRadius(double radius) {
this.radius = radius;
}
public double getRadius() {
return radius;
}
public void setColor(String color) {
this.color = color;
}
public String getColor() {
return color;
}
public Date getDateCreated() {
return dateCreated;
}
public double getArea(){
return Math.PI * radius * radius;
}
public double getPerimeter(){
return 2 * Math.PI * radius;
}
}
استفاده از کلاس Circle.
public class Main{
public static void main(String[] args){
Circle c0 = new Circle();
System.out.println("Circle created on " + c0.getDateCreated());
System.out.println("Radius is " + c0.getRadius());
System.out.println("Area " + c0.getArea());
System.out.println("Perimeter " + c0.getPerimeter());
Circle c1 = new Circle();
System.out.println("Circle created on " + c1.getDateCreated());
System.out.println("Radius is " + c1.getRadius());
System.out.println("Area " + c1.getArea());
System.out.println("Perimeter " + c1.getPerimeter());
}
}
مثال
تعریف کلاس TV.
public class TV {
private String panel;
private int channel = 1;
private int volume = 1;
private boolean on;
public TV(String panel){
this.panel = panel;
}
public TV(){
this("FLATIRON");
}
public void turnOn(){
on = true;
}
public void turnOff(){
on = false;
}
public void setChannel(int channel) {
if (on && channel >= 1 && channel <= 120)
this.channel = channel;
}
public void setVolume(int volume) {
if (on && volume >= 0 && volume <= 10)
this.volume = volume;
}
public String getPanel(){
return panel;
}
public int getChannel() {
return channel;
}
public int getVolume() {
return volume;
}
public void channelUp(){
if (on && channel < 120) channel++;
}
public void channelDown(){
if (on && channel > 1 ) channel --;
}
public void volumeUp(){
if (on && volume < 10)
volume++;
}
public void volumeDown(){
if (on && volume > 1)
volume --;
}
public boolean isOn() {
return on;
}
public boolean isMuted(){
return volume == 0;
}
}
ساخت نمونه و استفاده از TV.
public static void main(String[] args){
TV tv1 = new TV();
tv1.turnOn();
tv1.setChannel(30);
tv1.setVolume(3);
TV tv2 = new TV();
tv2.turnOn();
tv2.channelUp();
tv2.channelUp();
tv2.volumeUp();
System.out.println("tv1 has been built by " + tv1.getPanel() + " panel");
System.out.println("tv1's channel is " + tv1.getChannel() + " and volume level is " + tv1.getVolume());
System.out.println("tv2 has been built by " + tv2.getPanel() + " panel");
System.out.println("tv2's channel is " + tv2.getChannel() + " and volume level is " + tv2.getVolume());
}
خلاصه
- جاوا یک زبان کاملا شی گراست.
- در جاوا میتونیم کلاس تعریف کنیم و از کلاسمون یک یا چند آبجکت ایجاد کنیم.
- هر آبجکت مستقل از آبجکت های دیگس.
- یک کلاس در جاوا سه بخش اصلی داره: ۱- دیتافیلد ها ۲- کانستراکتور ها ۳- متد ها
- دیتافیلد های کلاس همان متغیر هایی هستند که داخل کلاس تعریف میکنیم و میتونیم داده های کلاس رو داخلشون ذخیره کنیم.
- کانستراکتور ها در جاوا متد های خاصی هستند که هیچ مقداری رو بر نمیگردونند.
- برای ایجاد آبجکت در جاوا نیاز داریم یکی از کانستراکتور های کلاس رو صدا بزنیم.
- یک کلاس میتونه یک یا چند متد داشته باشه.
- اگه یک دیتافیلد رو private تعریف کنیم اصطلاحا میگیم دیتافیلد رو کپسوله سازی کردیم و برای دسترسی بهش باید دو متد getter و setter براش تعریف کنیم.