Published on

Swiftda Inheritance

Authors

Boshqa OOP tillariga o'xshab, Swift ham class inheritance (meros olish) kontseptsiyasini qo'llab-quvvatlaydi.

Inheritance mavjud classdan yangi class yaratish imkonini beradi.

Yaratilgan yangi class subclass (child yoki derived class) deb ataladi va yangi class qaysi classdan olingan bo'lsa, u superclass (parent yoki base class) deb ataladi.

Inheritance sintaksisi

Swiftda bir classdan boshqa classni meros olish uchun ikki nuqta : belgisidan foydalanamiz. Masalan,

// superclass e'lon qilish
class Animal {
  // propertylar va metodlarni e'lon qilish
}

// inheritance
class Dog: Animal {

  // Animal classining propertylar va metodlari
  // Dog classining propertylar va metodlari
}

Bu yerda Dog subclassini Animal superclassidan meros oldik.

Misol:

class Animal {

  // superclassning propertysi va metodi
  var name: String = ""     // ism

  func eat() {
    print("Men ovqatlana olaman")
  }
}

// Animal classidan meros olish
class Dog: Animal {

  // subclassdagi yangi metod
  func display() {

    // superclassning name propertyga murojaat
    print("Mening ismim ", name);
  }
}

// subclassdan obyekt yaratish
var labrador = Dog()

// superclassning propertysi va metodiga murojaat
labrador.name = "Rohu"
labrador.eat()

// subclassning metodini chaqirish
labrador.display()

Natija:

Men ovqatlana olaman
Mening ismim Rohu

Yuqoridagi misolda Animal superclassidan Dog subclassini meros oldik. Quyidagi qatorlarga e'tibor bering:

labrador.name = "Rohu"

labrador.eat()

Bu yerda Animal classining name va eat() ga murojaat qilish uchun labrador (Dog obyekti)dan foydalanamiz. Bu mumkin, chunki subclass superclassning barcha property va metodlarini meros oladi.

Shuningdek, biz Dog classining metodi ichidan name propertyga murojaat qildik.

is-a munosabat

Swiftda inheritance is-a (hisoblanadi) munosabatidir. Ya'ni, biz inheritancedan faqat ikki class o'rtasida is-a munosabati mavjud bo'lsa foydalanamiz. Masalan,

  • Car is a Vehicle (Mashina — transport vositasi)
  • Apple is a Fruit (Olma — meva)
  • Cat is an Animal (Mushuk — hayvon)

Bu yerda Car classini Vehicle classidan, Apple classini Fruit classidan meros olish mumkin va hokazo.

Inheritanceda method overriding

Oldingi misolda subclass obyekti superclassning metodiga murojaat qilishi mumkinligini ko'rdik.

Ammo agar bir xil metod superclass va subclassda mavjud bo'lsa-chi?

Bunday holatda subclassdagi metod superclassdagi metodning ustidan yoziladi. Bu konseptsiya Swiftda method overriding deb ataladi.

Biz kompilyatorga metodning ustidan yozilayotganini bildirish uchun override kalit so'zidan foydalanamiz.

Misol:

class Animal {

 // superclassdagi metod
 func eat() {
   print("Men ovqatlana olaman")
 }
}

// Dog classi Animal classidan meros oladi
class Dog: Animal {

  // eat() metodining ustidan yozish
  override func eat() {
    print("Men boshqa ovqat yeyman")
  }
}

// subclassdan obyekt yaratish
var labrador = Dog()

// eat() metodini chaqirish
labrador.eat()

Natija:

Men boshqa ovqat yeyman

Yuqoridagi misolda bir xil eat() metodi Dog classida ham, Animal classida ham mavjud.

Endi Dog subclass obyekti yordamida eat() metodini chaqirganimizda, Dog classining metodi chaqiriladi.

Buning sababi, Dog subclassining eat() metodi Animal superclassining bir xil metodining ustidan yoziladi. Biz metod ustidan yozilishini bildirish uchun override kalit so'zidan foydalandik.

override func eat() {
  print("Men it ovqatini yeyman")
}

Inheritanceda super kalit so'zi

Avval ko'rganimizdek, subclassdagi bir xil metod superclassdagi metodning ustidan yoziladi.

Ammo agar subclassdan superclass metodiga murojaat qilishimiz kerak bo'lsa, super kalit so'zidan foydalanamiz. Masalan,

class Animal {

  // superclassda metod yaratish
  func eat() {
    print("Men ovqatlana olaman")
  }
}

// Dog classi Animal classidan meros oladi
class Dog: Animal {

  // eat() metodining ustidan yozish
  override func eat() {

  // superclass metodini chaqirish
  super.eat()
  print("Men boshqa ovqat yeyman")
  }
}

// subclassdan obyekt yaratish
var labrador = Dog()

// eat() metodini chaqirish
labrador.eat()

Natija:

Men ovqatlana olaman
Men boshqa ovqat yeyman

Yuqoridagi misolda Dog subclassining eat() metodi Animal superclassining bir xil metodining ustidan yoziladi.

Dog classi ichida

// superclass metodini chaqirish
super.eat()

dan foydalanib, Dog subclassidan Animal superclassining eat() metodini chaqirdik.

Shunday qilib, labrador obyekti yordamida eat() metodini chaqirganimizda

// eat() metodini chaqirish
labrador.eat()

Ham ustidan yozilgan, ham superclass versiyasidagi eat() metodi bajariladi.

Nima uchun Inheritance?

Inheritancening afzalliklarini tushunish uchun bir vaziyatni ko'rib chiqaylik.

Faraz qilaylik, biz muntazam ko'pburchaklar (kvadrat, beshburchak va hokazo) bilan ishlayapmiz. Va kiritilgan ma'lumotlarga asoslanib bu ko'pburchaklarning perimetrini topishimiz kerak.

  1. Barcha muntazam ko'pburchaklar uchun perimetrni hisoblash formulasi umumiy bo'lgani uchun, biz Polygon classi va perimetrni hisoblash uchun calculatePerimeter() metodini yaratishimiz mumkin.
class RegularPolygon {

  calculatePerimeter() {
    // perimetrni hisoblash kodi
  }
}
  1. Va Square va Pentagon classlarini RegularPolygon classidan meros olamiz. Bu classlarning har biri uzunlik va tomonlar sonini saqlash uchun propertyga ega bo'ladi, chunki ular barcha ko'pburchaklar uchun har xil.
class Square: RegularPolygon {

  var length = 0     // uzunlik
  var sides = 0      // tomonlar soni
}

Perimetrni hisoblash uchun calculatePerimeter() ga length va sides qiymatlarini uzatamiz.

Mana shunday qilib, inheritance kodimizni qayta ishlatish imkonini beradi va intuitiv qiladi.

Misol:

import Foundation
class RegularPolygon {

 func calculatePerimeter(length: Int, sides: Int) {
   var result = length * sides
   print("Perimetr:", result)
 }
}

// Square classini Polygon classidan meros olish
class RegularSquare: RegularPolygon {
 var length = 0     // uzunlik
 var sides = 0      // tomonlar soni

 func calculateArea() {
   var area = length * length
   print("Muntazam kvadrat yuzasi:", area)
 }
}

// Triangle classini Polygon classidan meros olish
class RegularTriangle: RegularPolygon {
 var length = 0.0     // uzunlik
 var sides = 0.0      // tomonlar soni

 func calculateArea() {
   var area = (sqrt(3)/4) * (length * length)
   print("Muntazam uchburchak yuzasi:", area)
 }
}

var shape = RegularSquare()
shape.length = 4
shape.calculateArea()
shape.calculatePerimeter(length: 3, sides: 4)

var shape2 = RegularTriangle()
shape2.length = 2
shape2.calculateArea()
shape2.calculatePerimeter(length: 2, sides: 3)

Natija:

Muntazam kvadrat yuzasi: 16
Perimetr: 12
Muntazam uchburchak yuzasi: 1.7320508075688772
Perimetr: 6

Yuqoridagi misolda muntazam ko'pburchakning perimetrini hisoblaydigan RegularPolygon classi yaratdik.

Bu yerda RegularSquare va RegularTriangle classlar RegularPolygon classidan meros oladi.

Muntazam ko'pburchakning perimetrini hisoblash formulasi barchasi uchun umumiy bo'lgani uchun, biz superclassning calculatePerimeter() metodini qayta ishlatdik.

Va yuzani hisoblash formulasi har xil shakllar uchun har xil bo'lgani uchun, yuzani hisoblash uchun subclass ichida alohida metod yaratdik.