Classes OOP

 

أولاً : طريقة إنشاء الصنف class :-

 

 

class Car {
    var name :String =""
    var color :String =""
    var model :Int = 0
    var price :Int = 0

    fun spead(sp:Int){
        if(sp > 100){
            println("Speed is slow")
        }
        else{
            println("High speed")
        }
    }
}

هنا مثال لـ Class السيارة وضعنا بداخله الصفات التي عرفنا اننا نمثلها برمجياً بالـ Variables وهي الاسم واللون والموديل والسعر مثلا ولكن نريد توضيح أمر عند تعريف المتغيرات بداخل التصنيف لابد من أن تقوم بتمهيد قيمة لهذا المتغير لأن لغة الـ kotlin لا تسمح لك بتعريفه بدون ان تمهد له ، ونلاحظ أيضا اننا لا نقوم بإعطاء قيمة حقيقية كما عرفنا فالقيم تعطى عند انشاء كائن أما هنا فنحن فقط نعطي الصفات والافعال .

 

طريقة أخرى لتمهيد قيم المتغيرات كالتالي :

 

var name :String? = null

 

الأن ستقول لي ما هو ناتج تنفيذ هذا الكود ؟ سأقول لك لا شيء ياعزيزي . نعم لا شيء ، لماذا لأننا فقط قمنا بإعلام البرنامج بإنشاء تصنيف يمرر له بيانات معينة فقط ، متى سينفذ الأمر ؟ وهذا هو الجزء الثاني المهم في درسنا وهو الكائن .


ثانياً : طريقة إنشاء كائن Object :-

الكائن يا عزيزي هو عبارة عن صورة للتصنيف الذي أنشأناه سأوضح لك الأمر مرة أخرى وهي أن السيارات جميعها بمختلف أنواعها تجتمع  بأن لها صفات مشتركة مثل الاسم فكل سيارة تحمل اسم وكل سيارة تحمل موديل ولون وسرعة فهنا ننشئ مصنف يضم كل الصفات والافعال التي تشترك فيها كل السيارات حسناً أين الاختلاف ؟ الاختلاف هو نوع البيان المدخل فسيارة من نوع فورد مختلفة عن سيارة نوع اودي وهكذا ، نقوم بإنشاء الكائن في داخل الدالة الرئيسية :-

var object1 = Car()

هكذا نحن انشأنا كائن عرفناه كما نقوم بتعريف المتغيرات ولكن الاختلاف هو أنه بعد علامة المساواة نضع اسم الصنف Class   الذي يتبعه الكائن الذي انشأناه ،يمكنك أيضا تعريف أكثر من كائن لنفس الصنف بشرط أن يكون الاسم مختلف .


ثالثاً : الوصول إلى المتغيرات الخاصة بالـ Class:-

طبعا الأن تعرف لدينا كائن من صنف السيارات إذا جميع ما عرفناه في داخل صنف السيارة ينطبق تماما على الكائن الذي انشأناه من اسم وموديل وسعر ولون ، وهنا السؤال كيف نستدعيهم ونقوم بتعبئتهم ؟

object1.name = "BMW"
object1.color = "White"
object1.model = 2017
object1.price = 90872.87f

كما نرى في كل مرة نريد الوصول إلى متغير أو دالة في داخل Class  نقوم بكتابة :

Object .Attribute

ومن ثم نقوم بالتعبئة كما نريد .

حسنا الأن تم تعبئة بيانات هذا الكائن سنقوم بعملية الطباعة لنرى ما سيحدث :-

println(object1.name)
println(object1.color)
println(object1.model)
println(object1.price)

ناتج التنفيذ :-

BMW

White

2017

90872.87


رابعاً : الوصول إلى الدوال الخاصة بالـ Class:-

من الممكن ان نستدعيها بداخل متغير ومن الممكن اجراء امر الطباعة مباشرة ، سوف نقوم باتباع نفس الطريقة:

var speed1 = object1.spead(150)println(speed1) 

 


خامساً : تمرير الوسائط في Class:-

بإمكاننا إنشاء تصنيف Class ونمرر له وسائط معينه :-

class labtop(id:Int,name:String) {

        var serialNum= id
        var companyName = name

        fun getInfo(){
                println("The labtop is : $companyName , and the serial number is : $serialNum")
            }

}

نلاحظ قمنا بإنشاء تصنيفclass  ومررنا له وسائط وهذا يعني أنه عندما نقوم بإنشاء كائن من هذا التصنيف يستوجب علينا تمرير قيم وسنرى ذلك في الدالة الرئيسية ،  وفي داخل التصنيف  عرفنا متغيرات واسندنا لها قيم هذي الوسائط الممررة وذلك لأن هذه وسائط بداخل تصنيف  لن يستطيع التعامل معها مباشرة ، ومن ثم قمنا بإنشاء دالة تطبع المعلومات .

في الدالة الرئيسية :

fun main (args:Array<String>){

        var dell = labtop(1015,"Dell")
        dell.getInfo()
}

نرى أنه ألزمنا عند إنشاء الكائن بتمرير قيم لهذه الوسائط التي ادخلناها في التصنيف فوق .

لو نريد أن نتعامل مع الوسائط  مباشرة بدون تعريف متغيرات في داخل تصنيفclass  :

class labtop(var id:Int,var name:String) {

       
        fun getInfo(){
                println("The labtop is : $name , and the serial number is : $id")
            }

}

 فقط نقوم بتعريفهم بداخل اقواس التصنيف .


سادساً : كلمة this:-

class labtop(var id:Int,var name:String) {

        fun setValues(id:Int , name:String){
                this.id = id
                this.name = name
            }

        fun getInfo(){
                println("The labtop is : $name , and the serial number is : $id")
            }

}

حسنا الأن سنتعرف على فائدة this   نلاحظ هنا أن انشأنا دالة ومررنا لها نفس المتغيرات للتصنيف class وبداخل الدالة :

this.id = id
this.name = name

هذه الكلمة تعني id الخاص بالتصنيف وليس id الممر للدالة ، لو كانت المتغيرات الممررة  للدالة ذات مسميات مختلفة عن التي تم تمريرها للتصنيف فلن نحتاج لهذه الكلمة ، باختصار شديد كلمة this   خاصة للوصول إلى محتويات التصنيف .


سابعاً : دالة البناء constructor:-

في البداية لابد من توضيح ماهية دالة البناء وعملها ؟

دالة البناء هي عبارة عن قطعة برمجية يتم تنفيذها مباشرة عند إنشاء كائن مشتق من التصنيف ،ويمكن إنشاء أكثر من دالة بناء بداخل التصنيف 

لدينا طريقتان لعمل دالة البناء :

الطريقة الأولى : دالة تعريف جاهزة init :

  • هذه الدالة اختصار لكلمة initialization .
  • لا نستطيع تمرير متغيرات بداخلها ابداً .
  • لها الأولوية في التنفيذ لو قمنا بإنشاء أكثر من دالة بناء .
  • نقوم بداخلها بتمهيد القيم وعند إنشاء كائن يتم استدعائها تلقائيا بدون القيام بكتابتها بنفسك وتنفيذ ما بداخلها .

 مثال :-

class employee(var firstName:String,var lastName:String,var titleJob:String,var salary :Double){

    init{
        println("the name of employee is :$firstName $lastName, his title job :$titleJob ,and his salary :$salary ")
    }

}

في المثال عرفنا المتغيرات بين اقواس التصنيف ومن ثم نلاحظ بداخل init فقط نريد طباعة هذه الجملة ، أي عن انشاء كائن من هذا التصنيف سوف يقوم بوضع قيم للمتغيرات وعند تنفيذ البرنامج سيطبع الجملة التي اردنا طباعتها في دالة التهيئة  .

في الدالة الرئيسية :-

var employee1 = employee("Ahmed","Aljuaid","Teacher",7000.0)

ناتج التنفيذ :-

the name of employee is :Ahmed Aljuaid, his title job :Teacher ,and his salary :7000.0


الطريقة الثانية : دالة  constructor :

  • نستطيع تمرير متغيرات بداخلها .
  • أيضا نقوم بداخلها بتمهيد القيم وعند إنشاء كائن يتم استدعائها تلقائيا بدون القيام بكتابتها بنفسك وتنفيذ ما بداخلها .

 مثال :-

سوف نقوم بتطبيق نفس المثال المذكور في init  :-

class employee{

        var firstName:String ? = null
        var lastName:String ? = null
        var titleJob:String ? = null
        var salary :Double ? = null

        constructor(fName:String,lName:String ,tJob:String ,sal :Double){
                firstName = fName
                lastName = lName
                titleJob = tJob
                salary = sal
                println("the name of employee is :$firstName $lastName, his title job :$titleJob ,and his salary :$salary ")

            }
    }

قمنا بتعريف متغيرات بداخل التصنيف ومن ثم انشأنا دالة بناء تمرر لها متغيرات وقمنا بإسناد هذه المتغيرات ومن ثم أمر الطباعة ، في الدالة الرئيسية :-

var employee1 = employee("Ahmed","Aljuaid","Teacher",7000.0)

ناتج التنفيذ :-

the name of employee is :Ahmed Aljuaid, his title job :Teacher ,and his salary :7000.0

 

 

 

 

 

 

 

 

 

تنويه :-

 

لو أردنا تمرير متغيرات عند إنشاء التصنيف فدالة البناء الـ constructor لا نستطيع التمرير لها ولكن نستعيض عنها بفعل الأتي :

class employee (var firstName:String,var lastName:String,var titleJob:String,var salary :Double){

        constructor():this("Ahmed","Aljuaid","Teacher",7000.0){

                println("the name of employee is :$firstName $lastName, his title job :$titleJob ,and his salary :$salary ")

            }

}

نلاحظ أننا استعملنا كلمة this  التي تقوم بالوصول إلى المتغيرات التي عرفناها عند إنشاء التصنيف .

وفي الدالة الرئيسية نقوم فقط بإنشاء كائن بدون تمرير :-

var employee1 = employee()

تتنوع هذه الطرق وكلاً بحسب حاجتك أنت عند إنشاء البرنامج وبحسب ما تراه .