GagorAcadmey

تعلم برمجة تطبيقات الاندرويد من الصفر حتي الاحتراف

آخر المواضيع

الثلاثاء، 4 سبتمبر 2018

Abstraction in java


مفهوم الـ Abstraction

تجريد: تعني Abstraction في اللغة الإنجليزية, و هو أسلوب مهم جداً يستخدم لتسهيل كتابة الأوامر على المبرمجين, فهو يجعلك قادراً على تنفيذ ما تريد دون الحاجة إلى معرفة كافة التفاصيل التي تم فيها تنفيذ ذلك. إذاً الـ Abstraction يجعلك تتعامل مع الأشياء بسطحية بدل أن تغوص في معرفة تفاصيل الكودات المعقدة.
فمثلاً إذا كنت تنوي بناء برنامج يتيح لمستخدميه إرسال إقتراحات حول التطبيق من خلال البريد الإلكتروني, في هذه الحالة لن يكون عليك القلق بتاتاً حول طريقة تعامل أوامر جافا مع البروتوكولات التي تعمل عندما يتم إرسال رسائل إلكترونية من خلال هذا التطبيق, لأنك لست مسؤولاً عنها, فعلياً هذه وظيفة شركة Sun التي تقوم بتطوير لغة جافا. و هم يخبرونك أنه لإرسال بريد إلكتروني إستخدم هذه الأوامر البسيطة فقط.
إذاً الـ Abstraction هو أسلوب يستخدم لإخفاء تفاصيل تنفيذ البرنامج. لتطبيق مفهوم الـ Abstraction نستخدم الكلمة abstract ضمن شروط محددة.

مصطلحات تقنية

إذا أردت تعريف الشيء كـ abstract, أكتب فقط الكلمة abstract قبله.
  1. الكلاس المعرف كـ abstract يسمى Abstract Class.

  2. الكلاس العادي الغير معرف كـ abstract يسمى Concrete Class.

  3. الدالة المعرفة كـ abstract تسمى Abstract Method أو Abstract Function.

Abstract Class

إذا وضعت الكلمة abstract قبل إسم الكلاس, ستتغير قليلاً طريقة التعامل معه لأنه لم يعد كلاس عادي. و عندها سيراه المترجم كـ Abstract Class.

نقاط مهمة حول الـ Abstract Class

  1. الكلاس العادي لا يمكنه أن يحتوي على دوال نوعها abstract.

  2. الـ Abstract Class يمكنه أن يحتوي على دوال عادية, و يمكنه أن يحتوي على دوال نوعها abstract.

  3. إذا قمت بتعريف الكلاس كـ abstract, فهذا يعني أن هذا الكلاس لا يمكن إنشاء كائنات منه.

  4. بما أنه لا يمكن إنشاء كائنات من Abstract Class, فهذا يعني أنه للإستفادة من هذا الكلاس, يجب وراثته.

  5. الكلاس الذي يرث من كلاس نوعه abstract, يجب أن يفعل Override لجميع الدوال المعرفة كـ abstract.

طريقة تعريف كلاس نوعه abstract

نكتب فقط الكلمة abstract قبل الكلمة class.

مثال

abstract class Example {}

Abstract Method

إذا كنت تريد بناء دالة و جعل الكلاس الذي يرثها هو المسؤول عن كتابتة محتواها, قم بتعريفها كـ abstract.

نقاط مهمة حول الـ Abstract Method

  1. إذا وضعت الكلمة abstract قبل إسم الدالة, فهذا يعني أنها دالة من النوع abstract.

  2. الدالة التي نوعها abstract هي دالة لها إسم و نوع محدد, لكنها لا تحتوي على body (جسم), أي لا تملك أقواس بداية و نهاية { }

  3. الدالة العادية تحتوي على أقواس البداية و النهاية { }

  4. الـ Abstract Method يجب وضع فاصلة منقوطة ; في آخرها بدل أقواس البداية و النهاية.

  5. الكلاس الذي يرث من كلاس نوعه abstract, يجب أن يفعل Override لكل دوالة نوعها abstract, أي يجب أن يكتب الـ body لهذه الدوال.

طريقة تعريف دوال نوعها abstract

نكتب فقط الكلمة abstract بعد Modifier الدالة.

أمثلة

public abstract void print();
public abstract int getId();
public abstract void setId(int id);
إنتبه: عندما تفعل Override لدالة نوعها abstract, يجب أن لا تعرفها كـ abstract من جديد.

لنفترض أننا قمنا بتعريف دالة إسمها displayMessage() كـ abstract
public abstract void displayMessage(); لا يجب أن نكتب abstract عندما تفعل لها Override.
    @Override
publicabstract void displayMessage() {//abstract methods cannot have a body
  }
لتصحيح هذا الخطأ, نمسح فقط الكلمة abstract.
    @Override
public void displayMessage() {// نلاحظ أن التنبيه إختفى
  }
أمثلة بسيطة و مترابطة تعلمك أساسيات الـ Abstraction
الآن سنقوم بتعريف كلاس إسمه A, نوعه abstract, يملك متغير إسمه x, و دالة إسمها print(). بعدها سنقوم ببناء الكلاس Test لتجربة الكود.

المثال الأول

A.java
package abstraction;
public abstract class A {   // إذاً لا يمكن إنشاء كائنات منه ,abstract نوعه A الكلاس
int x;
public void print() {
System.out.println("This is just an example.");
   }
}
Test.java
package abstraction;
public class Test {
public static void main(String[] args) {
A a = new A();   // Incompatible Type: abstraction.A is abstract; cannot be instantiated
   }
}
نتيجة التنفيذ :
Exception in thread "main" java.lang.RuntimeException:Uncompilable source span - abstraction.A is abstract; cannot be instantiated
سبب الخطأ هنا أننا حاولنا إنشاء كائن من كلاس نوعه abstract.
الآن سنقوم بإنشاء كلاس جديد إسمه B, يرث من الكلاس A. بداخل الكلاس Test سننشئ كائن من الكلاس B لنحصل على الأشياء الموجودة في الكلاس A.

المثال الثاني

A.java
package abstraction;
public abstract class A {
int x;
public void print() {
System.out.println("This is just an example.");
    }
}
B.java
package abstraction;
public class B extends A {   // إذاً سيرث كل شيء موجود فيه .A يرث من B هنا قلنا أن الكلاس
}
Test.java
package abstraction;
public class Test {
public static void main(String[] args) {
B b = new B();// B هنا قمنا بإنشاء كائن من الكلاس
b.print();// A من الكلاس B التي ورثها الكلاس print() هنا قمنا باستدعاء الدالة
b.x = 10;// A من الكلاس B الذي ورثه الكلاس x هنا قمنا بتغيير قيمة المتغير
System.out.println("b.x contain: " + b.x);    // x هنا قمنا بعرض قيمة المتغير
   }
}
نتيجة التنفيذ :
This is just an example. b.x contain: 10
إذاً بما أننا لا نستطيع إنشاء كائن مباشرةً من الكلاس A, قمنا بإنشاء الكلاس B بهدف وراثة الأشياء الموجودة في الكلاس A, و بعدها أنشأنا كائن من الكلاس B و تأكدنا أنه يحتوي على جميع الأشياء الموجودة في الكلاس A.
الآن سنقوم بإضافة دالتين نوعهما abstract في الكلاس A, ثم سنفعل لهما Override في الكلاس B. بداخل الكلاس Test سننشئ كائن من الكلاس B و سنقوم باستدعاء الدوال الجديدة التي قمنا بإضفاتها.

المثال الثالث

A.java
package abstraction;
public abstract class A {
int x;
public void print() {
System.out.println("This is just an example.");
 }
public abstract void setX(int x);// كل كلاس يرثها Override إذاً يجب أن يفعل لها
public abstract int getX();// كل كلاس يرثها Override إذاً يجب أن يفعل لها
  }
B.java
package abstraction;
public class B extends A {// abstract لأي دالة سيرثها من النوع Override يجب أن يفعل A يرث من الكلاس B بما أن الكلاس
// setX() للدالة Override هنا فعلنا
    @Override
public void setX(int x) {
super.x = x;
   }
// setX() للدالة Override هنا فعلنا
    @Override
public int getX() {
return super.x;
    }
}
Test.java
package abstraction;
public class Test {
public static void main(String[] args) {
B b = new B();// B هنا قمنا بإنشاء كائن من الكلاس
b.print();// A من الكلاس B التي ورثها الكلاس print() هنا قمنا باستدعاء الدالة
b.setX(55);// setX() عن طريق الدالة A من الكلاس B الذي ورثه الكلاس x هنا قمنا بتغيير قيمة المتغير
System.out.println("b.x contain: " + b.getX());    // getX() عن طريق الدالة  x هنا قمنا بعرض قيمة المتغير
   }
}
نتيجة التنفيذ :
This is just an example. b.x contain: 55

مثال بسيط في جافا حول Abstract Class يرث من Abstract Class

الآن سنقوم بتعريف كلاس إسمه A نوعه abstract, يملك متغير إسمه x, و دالة إسمها print1() نوعها abstract. بعدها سنقوم بتعريف كلاس إسمه B نوعه abstract يرث من الكلاس A, يملك دالة إسمها print2() نوعها abstract. بعدها سنقوم بتعريف كلاس إسمه C, يرث من الكلاس B. في الأخير سنقوم ببناء الكلاس Test لتجربة الكود.
A.java
package abstraction;
public abstract class A {
int x;
public abstract void print1();
}
B.java<
package abstraction;
public abstract class B extends A {
public abstract void print2();
// print1() أيضاً ورث الدالة B لا تنسى أن الكلاس
}
C.java
package abstraction;
public class C extends B {
// B التي ورثها من الكلاس abstract لجميع الدوال التي نوعها Override يجب أن يفعل C الكلاس
   @Override
public void print1() {
System.out.println("Class C shoold override the method print1()");
}
   @Override
public void print2() {
System.out.println("Class C shoold override the method print2()");
}
}
Test.java
package abstraction;
public class Test {
public static void main(String[] args) {
C c = new C();   // C هنا قمنا بإنشاء كائن من الكلاس
c.print1();// Override و فعل لها C التي ورثها الكلاس print1() هنا قمنا باستدعاء الدالة
c.print2();// Override و فعل لها C التي ورثها الكلاس print2() هنا قمنا باستدعاء الدالة
    }
}
نتيجة التنفيذ :
Class C shoold override the method print1()
Class C shoold override the method print2()

مثال مهم يعلمك متى تحتاج إلى إنشاء Abstract Class

الآن سنقوم ببناء كلاس إسمه Person نوعه abstract, يملك أربعة خصائص نوعهم private إسمهم name, gender, brithday و isMarried, و يملك دوال Setter and Getter لهذه الخصائص, و يملك أيضاً دالة إسمها displayInfo() نوعها abstract.
بعدها سنقوم بتعريف كلاس إسمه Student يرث من الكلاس Person و يملك متغير إضافي إسمه specialization.
بعدها سنقوم بتعريف كلاس إسمه Employee يرث من الكلاس Person و يملك متغير إضافي إسمه workPlace.
الفكرة هنا أن أي كلاس سيتم إنشاءه لتمثيل إنسان يجب أن يرث من الكلاس Person الذي يملك الخصائص المشتركة لكل البشر.
في الأخير سنقوم ببناء الكلاس Test لتجربة الكود.

Person.java
package abstraction;
public abstract class Person {
// هنا قمنا بتعريف الخصائص المشتركة لدى جميع البشر
String name;
String gender;
String birthday;
boolean isMarried;
// هنا قمنا بتعريف الكونستركتور
public Person(String n, String g, String b, boolean i) {
name = n;
gender = g;
birthday = b;
isMarried = i;
}
// Getter هنا قمنا بتعريف دوال الـ
public String getName() {
return name;
}
public String getGender() {
return gender;
}
public String getBirthday() {
return birthday;
}
public boolean getIsMarried() {
return isMarried;
}
 // Setter هنا قمنا بتعريف دوال الـ
public void setName(String n) {
name = n;
}
public void setGender(String g) {
gender = g;
}
public void setBirthday(String b) {
birthday = b;
 }
public void setIsMarried(boolean i) {
isMarried = i;
}
// abstract و التي نوعها displayInfo() هنا قمنا بتعريف الدالة
public abstract void displayInfo();
}
Student.java
package abstraction;
public class Student extends Person {
String specialization;   // هنا قمنا بتعريف خاصية التخصص و التي يملكها فقط التلاميذ
// هنا قمنا بتعريف الكونستركتور
public Student(String n, String g, String b, boolean i, String s) {
super(n, g, b, i);    // Person هنا سيتم إرسال أول أربع قيم إلى كونستركتور الكلاس
specialization = s;
}
// بشكل ملائم للتلامذة displayInfo() للدالة Override هنا فعلنا
    @Override
public void displayInfo() {
System.out.println("Name: " + getName());
System.out.println("Gender: " + getGender());
System.out.println("Birthday: " + getBirthday());
System.out.println("Specialization: " + specialization);
System.out.println("---------------------------------");
 }
}
Employee.java
package abstraction;
public class Employee extends Person {
String workPlace;   // هنا قمنا بتعريف خاصية مكان العمل و التي يملكها فقط الموظفون و العمال
// هنا قمنا بتعريف الكونستركتور
public Employee(String n, String g, String b, boolean i, String w) {
super(n, g, b, i);    // Person هنا سيتم إرسال أول أربع قيم إلى كونستركتور الكلاس
workPlace = w;
}
// بشكل ملائم للموظفين أو العمال displayInfo() للدالة Override هنا فعلنا
   @Override
public void displayInfo() {
System.out.println("Name: " + getName());
System.out.println("Gender: " + getGender());
System.out.println("Birthday: " + getBirthday());
if(getIsMarried() == true)
System.out.println("is Married: yes");
else
System.out.println("is Married: no");
System.out.println("Work place: " + workPlace);
System.out.println("---------------------------------");
}
}

Test.java
package abstraction;
public class Test {
public static void main(String[] args) {
// و هو عبارة عن إنسان له خصائص طالب Student هنا قمنا بإنشاء كائن من الكلاس
Student s = new Student("Mhamad", "Male", "1994", false, "Computer Science");
s.displayInfo();
// و هو عبارة عن إنسان له خصائص موظف أو عامل Employee هنا قمنا بإنشاء كائن من الكلاس
Employee e = new Employee("Rana", "Female", "1986", true, "Al-Iman school");
e.displayInfo();
   }
}
سنحصل على النتيجة التالية عند التشغيل.
Name: Mhamad
            Gender: Male
            Birthday: 1994
            Specialization: Computer Science
            ---------------------------------
            Name: Rana
            Gender: Female
            Birthday: 1986
            is Married: yes
            Work place: Al-Iman school
            ---------------------------------

ليست هناك تعليقات:

إرسال تعليق

ملحوظة: يمكن لأعضاء المدونة فقط إرسال تعليق.

صفحتنا علي الفيسبوك

التسميات

المتواجدين حاليا