Menu
Coddy logo textTech

final ve Hiyerarşiler

Coddy'nin Swift Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 25 / 57.

final daha fazla geçersiz kılmayı engeller. Bir final func herhangi bir alt sınıfta geçersiz kılınamaz ve bir final class hiçbir şekilde alt sınıflara ayrılamaz:

class Account {
    final func id() -> String { "ACC" }   // üzerine yazılamaz
}

final class Receipt { }                  // alt sınıf oluşturulamaz
// class GiftReceipt: Receipt { }        // error: final bir sınıftan kalıtım

Alt sınıfların onu değiştirmemesi gerektiğinde, örneğin bir kuralı uygulayan bir yöntemi final olarak işaretleyin. Diğer yöntemler, ayrıntıları özelleştirmek için yine geçersiz kılınabilir:

class Checkout {
    final func total(_ prices: [Int]) -> Int {
        let sum = prices.reduce(0, +)
        return sum - discount(sum)
    }
    func discount(_ sum: Int) -> Int { 0 }
}

class SaleCheckout: Checkout {
    override func discount(_ sum: Int) -> Int { sum / 10 }
}

print(Checkout().total([50, 50]))
print(SaleCheckout().total([50, 50]))

Çıktı:

100
90

Hiyerarşiler birkaç seviyeye sahip olabilir. Bir metot, nesnenin kendi sınıfından başlayarak yukarı doğru aranır ve bulunan ilk uygulama çalıştırılır:

class Animal {
    func move() -> String { "moves" }
    func eat() -> String { "eats" }
}
class Bird: Animal {
    override func move() -> String { "flies" }
}
class Penguin: Bird {
    override func move() -> String { "swims" }
}

let p = Penguin()
print(p.move())
print(p.eat())

Çıktı:

swims
eats

Hiyerarşileri sığ tutun. Derin zincirleri takip etmek zordur, çünkü bir nesnenin davranışı birçok sınıfa yayılmıştır. Türler bir is-a ilişkisi olmadan davranış paylaşıyorsa, protokoller (sonraki bölüm) genellikle daha iyi bir araçtır.

// derin ve kırılgan
class A { }
class B: A { }
class C: B { }
class D: C { }      // D neyi miras alır ve nereden?
challenge icon

Görev

Kolay

Discount, fiyat eksi amount(for:) değerini döndüren, ancak sonucu hiçbir zaman 0'ın altına düşürmeyen bir final yöntem olan apply(to:) yöntemine sahiptir ve amount(for:) 0 döndürür. Saklanan percent değerine sahip olan ve tutarı fiyat çarpı yüzde / 100 şeklinde hesaplanan PercentOff ile saklanan value değerine sahip olan ve tutarı value olan FixedOff sınıflarını tanımlayın; her birinde bir başlatıcı ve amount(for:) yönteminin bir geçersiz kılınmış sürümü bulunmalıdır. apply(to:) yöntemi kendisi Discount içinde kalır.

Sağlanan kod fiyatı okur, ardından p,10 veya f,300 indirimlerini alır, her birini fiyata uygular ve 1000 -> 900 çıktısını yazdırır.

Kodunuz Discount.swift, PercentOff.swift ve FixedOff.swift dosyalarına yazılmalıdır. main.swift sağlanan giriş/çıkış kodunu içerir ve düzenlenemez.

Kendin dene

// Sağlanan girdi/çıktı kodu: olduğu gibi bırakın
var input: [String] = []
while let line = readLine() { input.append(line) }
let price = Int(input[0])!
for line in input.dropFirst() {
    let p = line.split(separator: ",").map(String.init)
    let d: Discount = p[0] == "p" ? PercentOff(percent: Int(p[1])!) : FixedOff(value: Int(p[1])!)
    print("\(price) -> \(d.apply(to: price))")
}
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Yönelimli Programlama bölümündeki tüm dersler

Kendi başına pratik yap: Swift playground