GagorAcadmey

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

آخر المواضيع

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

التحميل الزائد للدوال

مفهوم الـ Overloading

Overloading: تعني تعريف أكثر من دالة أو كونستركتور, لهم نفس الإسم, مختلفون في عدد أو نوع الباراميترات.
الفكرة من الـ Overloading, هي تجهيز عدة دوال لهم نفس الإسم, هذه الدوال تكون متشابهة من حيث الوظيفة, مختلفة قليلاً في الأداء.
فعلياً, تكون كل دالة تحتوي على ميزات إضافية عن الدالة التي أنشأت قبلها.

شروط الـ Overloading

  1. الـ Overloading يطبق فقط على الدوال و الـ Constructors.

  2. يجب أن يملكوا نفس الإسم.

  3. يجب أن يختلفوا في نوع أو عدد الباراميترات.

  4. نوع الإرجاع غير مهم, لا يستطيع المترجم التفريق بين الدوال إذا كانوا مختلفين في نوع الإرجاع.

أمثلة شاملة حول الـ Overloading


المثال الأول

تعريف دوال لها نفس الإسم و تختلف في نوع الباراميترات.
لنفترض أننا قمنا بتعريف كلاس إسمه MyMethods, يحتوي على ثلاث دوال إسمهم sum() و نوعهم public void.
الدالة الأولى مهمتها جمع أي عددين نوعهما int ثم طباعة قيمتهم.
الدالة الثانية مهمتها جمع أي عددين نوعهما float ثم طباعة قيمتهم.
الدالة الثالثة مهمتها جمع أي عددين نوعهما double ثم طباعة قيمتهم.
بعد إنشاء هذا الكلاس, سنقوم بإنشاء الكلاس Main و إستدعاء الدوال الثلاثة فيه.

مثال

MyMethods.java
public class MyMethods {

public void sum(int a, int b) {
System.out.println("First method is called ====> "+a+" + "+b+" = "+(a+b));
}

public void sum(float a, float b) {
System.out.println("Second method is called ===> "+a+" + "+b+" = "+(a+b));
}

public void sum(double a, double b) {
System.out.println("Third method is called ====> "+a+" + "+b+" = "+(a+b));
}
}
Main.java
public class Main {
public static void main(String[] args) {

MyMethods m = new MyMethods();// لإستدعاء الدوال منه MyMethods هنا قمنا بإنشاء كائن من الكلاس
m.sum(1000, 4000);// int هنا سيتم إستدعاء الدالة التي تأخذ 2 باراميتر نوعهم
m.sum(10f, 40f);// float هنا سيتم إستدعاء الدالة التي تأخذ 2 باراميتر نوعهم
m.sum(10d, 40d);// double هنا سيتم إستدعاء الدالة التي تأخذ 2 باراميتر نوعهم

System.out.println();
m.sum(2000, -100);// int هنا سيتم إستدعاء الدالة التي تأخذ 2 باراميتر نوعهم
m.sum(5.5, -3.3);// لأن الأرقام تحتوي على فاصلة double هنا سيتم إستدعاء الدالة التي تأخذ 2 باراميتر نوعهم
m.sum(5.5d, -3.3d);// double هنا سيتم إستدعاء الدالة التي تأخذ 2 باراميتر نوعهم
m.sum(5.5f, -3.3f);// بعد كل رقم f لأننا وضعنا float هنا سيتم إستدعاء الدالة التي تأخذ 2 باراميتر نوعهم

System.out.println();
m.sum(6, 5.25);// يقبل كلا النوعين double لأن النوع double هنا سيتم إستدعاء الدالة التي تأخذ 2 باراميتر نوعهم
m.sum(6, 5.25f);// يقبل كلا النوعين float لأن النوع float هنا سيتم إستدعاء الدالة التي تأخذ 2 باراميتر نوعهم
m.sum(6, 5.25d);// يقبل كلا النوعين double لأن النوع double هنا سيتم إستدعاء الدالة التي تأخذ 2 باراميتر نوعهم
}
}
سنحصل على النتيجة التالية عند التشغيل.
First method is called ====> 1000 + 4000 = 5000
Second method is called ===> 10.0 + 40.0 = 50.0
Third method is called ====> 10.0 + 40.0 = 50.0
First method is called ====> 2000 + -100 = 1900
Third method is called ====> 5.5 + -3.3 = 2.2
Third method is called ====> 5.5 + -3.3 = 2.2
Second method is called ===> 5.5 + -3.3 = 2.2
Third method is called ====> 6.0 + 5.25 = 11.25
Second method is called ===> 6.0 + 5.25 = 11.25
Third method is called ====> 6.0 + 5.25 = 11.25

كما لاحظت هنا, في كل مرة قمنا فيها باستدعاء الدالة sum(), وجدنا أن المترجم قام باستدعاء الدالة sum() المناسبة لنوع الباراميترات الذي كنا نمرره لها.


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

تعريف دوال لها نفس الإسم و تختلف في عدد الباراميترات.
لنفترض أننا قمنا بتعريف كلاس إسمه MyInfo, يحتوي على ثلاث دوال إسمهم displayInfo() و نوعهم public void.
الدالة الأولى تأخذ باراميتر واحد عبارة عن الإسم, ثم تقوم بطباعته.
الدالة الثانية تأخذ إثنين باراميتر عبارة عن الإسم و إسم العائلة, ثم تقوم بطباعتهما.
الدالة الثالثة تأخذ ثلاثة باراميترات عبارة عن الإسم و إسم العائلة و الوظيفة, ثم تقوم بطباعتهم.

بعد إنشاء هذا الكلاس, سنقوم بإنشاء الكلاس Main و إستدعاء الدوال الثلاثة فيه.

مثال

MyInfo.java
public class MyInfo {

public void displayInfo(String name) {
System.out.println("name: " +name);
System.out.println("---------------------");
}

public void displayInfo(String name, String lastName) {
System.out.println("name: " +name); System.out.println("last name: " +lastName);
System.out.println("---------------------");
}

public void displayInfo(String name, String lastName, String job) {
System.out.println("name: " +name);
System.out.println("last name: " +lastName);
System.out.println("job: " +job);
System.out.println("---------------------");
}
}
Main.java
public class Main {

public static void main(String[] args) {
MyInfo m = new MyInfo();// لإستدعاء الدوال منه MyInfo هنا قمنا بإنشاء كائن من الكلاس
m.displayInfo("ahmed");// هنا سيتم إستدعاء الدالة التي تأخذ باراميتر واحد
m.displayInfo("Mohmmed", "gagoor");// هنا سيتم إستدعاء الدالة التي تأخذ 2 باراميتر
m.displayInfo("ahmed", "gagoor", "programmer");// هنا سيتم إستدعاء الدالة التي تأخذ 3 باراميترات
}
}
سنحصل على النتيجة التالية عند التشغيل.
name: ahmed
---------------------
name: Mohmmed
last name: gagoor
---------------------
name: ahmed
last name: gagoor
job: programmer
---------------------

كما لاحظت هنا, في كل مرة قمنا فيها باستدعاء الدالة displayInfo(), وجدنا أن المترجم قام باستدعاء الدالة displayInfo() التي تحتوي على نفس عدد الباراميترات الذي كنا نمرره لها.

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

تعريف دوال تعتمد على دوال موجودة قبلها في نفس الكلاس.
المثال التالي هو من أهم أمثلة الـ Overloading لأننا سنبني دوال تعتمد على دوال موجودة قبلها.
الآن لنفترض أننا قمنا بتعريف كلاس إسمه MyMath, يحتوي على ثلاث دوال إسمهم max() و نوعهم public double.
  1. الدالة الأولى تأخذ 2 باراميتر عبارة عن أرقام, و هي تعطينا العدد الأكبر بينهما.

  2. الدالة الثانية تأخذ 3 باراميترات عبارة عن أرقام, و هي تعطينا العدد الأكبر بينهم.

  3. الدالة الثالثة تأخذ 4 باراميترات عبارة عن أرقام, و هي تعطينا العدد الأكبر بينهم.

بعد إنشاء هذا الكلاس, سنقوم بإنشاء الكلاس Main و إستدعاء الدوال الثلاثة فيه.

مثال

MyMath.java
package overloading;
public class MyMath {

// هذه الدالة تعطيها رقمين فترجع لك العدد الأكبر بينهما
public double max(double a, double b) {
if(a>b)
return a;
else
return b;
}

// هذه الدالة تعطيها ثلاثة أرقام فترجع لك العدد الأكبر بينهم
// و هي تعتمد على الدالة السابقة لمقارنة أول عددين مع العدد الثالث
public double max(double a, double b, double c) { if(max(a,b)>c)
return max(a,b);
else
return c;
}

// هذه الدالة تعطيها ثلاثة أرقام فترجع لك العدد الأكبر بينهم
// و هي تعتمد على الدالتين السابقتين لمقارنة أول ثلاث أعداد مع العدد الرابع
public double max(double a, double b, double c, double d) {
if(max(a,b,c)>d)
return max(a,b,c);
else
return d;
}
}
Main.java
public class Main {

public static void main(String[] args) {
MyMath m = new MyMath();// لإستدعاء الدوال منه MyMath هنا قمنا بإنشاء كائن من الكلاس
System.out.println("The max number is: " +m.max(5, 20));// هنا سيتم إستدعاء الدالة التي تأخذ 2 باراميتر
System.out.println("The max number is: " +m.max(5, 20, 15));// هنا سيتم إستدعاء الدالة التي تأخذ 3 باراميترات
System.out.println("The max number is: " +m.max(5, 20, 15, 30));// هنا سيتم إستدعاء الدالة التي تأخذ 4 باراميترات
}
}
سنحصل على النتيجة التالية عند التشغيل.
The max number is: 20.0
The max number is: 20.0
The max number is: 30.0

كما لاحظت هنا, في كل مرة قمنا فيها باستدعاء الدالة max(), وجدنا أن المترجم قام باستدعاء الدالة max() التي تحتوي على نفس عدد الباراميترات الذي كنا نمرره لها, و داخلياً ربطنا الدوال ببعضها.

المثال الرابع

تعريف دوال تعتمد على دوال موجودة في الـ Superclass.
المثال التالي هو من أهم أمثلة الـ Overloading لأننا سنبني دالة في الـ Subclass تعتمد على دالة موجودة في الـ Superclass.
الآن لنفترض أننا قمنا بتعريف كلاس إسمه MyMath1, يحتوي دالة إسمها max(), الهدف من هذه الدالة مقارنة أي عددين نمررهما لها كـ Arguments ثم إرجاع العدد الأكبر بينهما. بعد مدة قررنا إنشاء نسخة متطورة من هذا الكلاس إسمها MyMath2 تعتمد على الكلاس MyMath1, إذاً الكلاس الجديد يحتوي على نسخة متطورة من الدالة max() تقارن ثلاث أرقام.
بعد إنشاء هذه الكلاسات, سنقوم بإنشاء الكلاس Main و إستدعاء كلا الدالتين فيه من خلال اكائن من االكلاس MyMath2.

مثال

MyMath1.java
public class MyMath1 {

// هذه الدالة تعطيها رقمين فترجع لك العدد الأكبر بينهما
public double max(double a, double b) {
if(a>b)
return a;
else
return b;
}
}
MyMath2.java
public class MyMath2 extends MyMath1 {

// هذه الدالة تعطيها ثلاثة أرقام فترجع لك العدد الأكبر بينهم
// Superclass الموروثة من الـ max() و هي تعتمد على الدالة
public double max(double a, double b, double c) {
if(max(a,b)>c)
return max(a,b);
else
return c;
}
}
Main.java
public class Main {

public static void main(String[] args) {
MyMath2 m = new MyMath2();// لإستدعاء الدوال منه MyMath2 هنا قمنا بإنشاء كائن من الكلاس
System.out.println("The max number is: " +m.max(25, 14));// هنا سيتم إستدعاء الدالة التي تأخذ 2 باراميتر
System.out.println("The max number is: " +m.max(25, 14, 35));// هنا سيتم إستدعاء الدالة التي تأخذ 3 باراميترات
}
}
سنحصل على النتيجة التالية عند التشغيل.
The max number is: 25.0
The max number is: 35.0

كما لاحظت هنا أن الـ MyMath2 يملك دلتين إسمهم max(), الأولى هي التي ورثها من الـ MyMath1, و الثانية التي قمنا بتعريفها فيه.
في كل مرة قمنا فيها باستدعاء الدالة max(), وجدنا أن المترجم قام باستدعاء الدالة max() التي تحتوي على نفس عدد الباراميترات الذي كنا نمرره لها, و داخلياً ربطنا الدوال ببعضها.

المثال الخامس

تعريف أكثر من كونستركتور في الكلاس.
المثال التالي هو من أهم أمثلة الـ Overloading لأننا سنقوم بتجهيز أكثر من كونستركتور للكلاس حتى نسهل طريقة خلق كائنات منه.
الآن لنفترض أننا قمنا بتعريف كلاس إسمه Country ( أي بلد ), يحتوي على أربعة Constructors.
الكونستركتور الأول لا يأخذ أي باراميتر.
الكونستركتور الثاني يأخذ باراميتر واحد عبارة عن إسم البلد.
الكونستركتور الثالث يأخذ إثنين باراميتر عبارة عن إسم و مساحة البلد.
الكونستركتور الرابع تأخذ ثلاثة باراميترات عبارة عن إسم و مساحة و عدد سكان البلد.

بعد إنشاء هذا الكلاس, سنقوم بإنشاء الكلاس Main و إنشاء أربعة كائنات من الكلاس Country.

مثال

Country.java
public class Country {

// سيملك هذه الخصائص, أي كل بلد سيملك هذه الخصائص Country كل كائن من الكلاس
public String name;
public double area;
public long population;
// الكونستركتور الأول لا يأخذ باراميترات
public Country() {

}
// الكونستركتور الثاني يتيح لك تحديد إسم البلد مباشرةً عند إنشاء الكائن
public Country(String n) {
name = n;
}
// الكونستركتور الثالث يتيح لك تحديد إسم البلد و مساحته مباشرةً عند إنشاء الكائن
public Country(String n, double a) {
name = n;
area = a;
}
// الكونستركتور الرابع يتيح لك تحديد إسم البلد و مساحته و عدد السكان مباشرةً عند إنشاء الكائن
public Country(String n, double a, long p) {
name = n;
area = a;
population = p;
}
// هذه الدالة تعرض جميع المعلومات التي تم إدخالها في الكائن
public printInfo() {
System.out.println("name: " + name);
System.out.println("area: " + area);
System.out.println("population: " + population);
}
}
Main.java
public class Main {

public static void main(String[] args) {
// هنا كل كائن يمثل بلد ,Country هنا قمنا بإنشاء 4 كائنات من الكلاس
Country c1 = new Country();// c1 هنا سيتم إستدعاء الكونستركور الأول, لن يتم تحديد أي معلومة حول البلد الذي يمثله الكائن
Country c2 = new Country("KSA");// c2 هنا سيتم إستدعاء الكونستركور الثاني, أي سيتم تحديد إسم البلد الذي يمثله الكائن
Country c3 = new Country("sudan", 20000);// c3 هنا سيتم إستدعاء الكونستركور الثالث, أي سيتم تحديد إسم و مساحة البلد الذي يمثله الكائن
Country c4 = new Country("cairo", 34344, 656666);// c4 هنا سيتم إستدعاء الكونستركور الربع, أي سيتم تحديد إسم و مساحة و عدد سكان البلد الذي يمثله الكائن
// لعرض خصائص جميع الكائنات printInfo() هنا قمنا باستدعاء الدالة
c1.printInfo();
c2.printInfo();
c3.printInfo();
c4.printInfo();
}
}
سنحصل على النتيجة التالية عند التشغيل.
name: null
area: 0.0
population: 0
-------------------
name: KSA
area: 0.0
population: 0
-------------------
name: sudan
area: 20000.0
population: 0
-------------------
name: cairo
area: 34344.0
population: 656666
-------------------

كما لاحظت هنا أن الـ Country يملك أربعة Constructors إسمهم Country(), و كل Constructor منهم يتيح لك تحديد معلومات معينة مباشرةً عند إنشاء كائن من الكلاس Country.
في كل مرة قمنا فيها باستدعاء الكونستركتور Country(), وجدنا أن المترجم قام باستدعاء الكونستركتور Country() الذي يحتوي على نفس عدد الباراميترات الذي كنا نمرره له.

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

إرسال تعليق

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

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

التسميات

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