সুইফটে একটি সঞ্চিত সম্পত্তি ওভাররাইড করা


126

আমি লক্ষ্য করেছি যে সংকলকটি আমাকে অন্য একটি সঞ্চিত মান (যা দেখতে অদ্ভুত বলে মনে হয়) সহ একটি সঞ্চিত সম্পত্তি ওভাররাইড করতে দেয় না:

class Jedi {
    var lightSaberColor = "Blue"
}


class Sith: Jedi {
    override var lightSaberColor = "Red" // Cannot override with a stored property lightSaberColor
}

তবে, একটি গণিত সম্পত্তি দিয়ে আমাকে এটি করার অনুমতি দেওয়া হয়েছে:

class Jedi {
    let lightSaberColor = "Blue"
}


class Sith: Jedi {
    override var lightSaberColor : String{return "Red"}

}

আমাকে কেন এটিকে অন্য মূল্য দেওয়ার অনুমতি দেওয়া হচ্ছে না?

কেন একটি সঞ্চিত সম্পত্তিটিকে ঘৃণা করা এবং গণনা করা কোনও কোশার দিয়ে এটি করা হচ্ছে? তারা কোথায় ভাবছে?


উত্তর:


82

আমাকে কেন এটিকে অন্য মান দেওয়ার অনুমতি দেওয়া হচ্ছে না?

উত্তরাধিকার সূত্রে প্রাপ্ত সম্পত্তিকে আলাদা মান দেওয়ার জন্য আপনাকে অবশ্যই অনুমতি দেওয়া হয়েছে। আপনি যদি কোনও কনস্ট্রাক্টরতে সম্পত্তিটি আরম্ভ করেন যা সেই প্রাথমিক মানটি গ্রহণ করে এবং উত্পন্ন শ্রেণি থেকে আলাদা মানটি পাস করে তবে আপনি এটি করতে পারেন:

class Jedi {
    // I made lightSaberColor read-only; you can make it writable if you prefer.
    let lightSaberColor : String
    init(_ lsc : String = "Blue") {
        lightSaberColor = lsc;
    }
}

class Sith : Jedi {
    init() {
        super.init("Red")
    }
}

let j1 = Jedi()
let j2 = Sith()

println(j1.lightSaberColor)
println(j2.lightSaberColor)

কোনও সম্পত্তিকে ওভাররাইড করা নতুন মান দেওয়ার মতো নয় - এটি আরও অনেক বেশি শ্রেণীর একটি আলাদা সম্পত্তি দেওয়ার মতো। প্রকৃতপক্ষে, আপনি যখন কোনও গণিত সম্পত্তি ওভাররাইড করবেন তখনই এটি ঘটে: বেস ক্লাসে সম্পত্তিটি গণনা করা কোডটি কোড দ্বারা প্রতিস্থাপিত করা হয় যা উত্পন্ন শ্রেণিতে সেই সম্পত্তিটির জন্য ওভাররাইডকে গণনা করে।

[কী] আসল সঞ্চিত সম্পত্তিটিকে ওভাররাইড করা সম্ভব, অর্থাৎ এর সাথে lightSaberColorঅন্য কিছু আচরণ রয়েছে?

পর্যবেক্ষক ছাড়াও, সঞ্চিত বৈশিষ্ট্যের আচরণ নেই, তাই ওভাররাইড করার মতো সত্যিকারের কিছুই নেই। উপরে বর্ণিত প্রক্রিয়াটির মাধ্যমে সম্পত্তিটিকে আলাদা মান প্রদান করা সম্ভব। এটি প্রশ্নের বাক্সের উদাহরণটি ভিন্ন সিনট্যাক্স সহ যা অর্জন করার চেষ্টা করছে ঠিক তা করে।


2
@ ম্যাক্সম্যাকলিউড পর্যবেক্ষক ছাড়াও, সঞ্চিত বৈশিষ্ট্যের আচরণ নেই, সুতরাং ওভাররাইড করার মতো সত্যিকারের কিছুই নেই। তিনি একটি সঞ্চিত সম্পত্তি সাবক্লাসে একটি আলাদা মূল্য দিতে চেয়েছিলেন, তবে এটি অর্জনের প্রক্রিয়া সম্পর্কে তিনি অনিশ্চিত ছিলেন। উত্তরটি কীভাবে এটি সুইফটে করা যায় তা ব্যাখ্যা করে। দেরী জবাবের জন্য আমি দুঃখিত, মনে হচ্ছে আপনার মন্তব্যটি ডাউনভোটদের আকর্ষণ করার জন্য যথেষ্ট বিভ্রান্তি সৃষ্টি করে, তাই আমি কী চলছে তা ব্যাখ্যা করার সিদ্ধান্ত নিয়েছি।
ডেসব্লিংকনলাইট

55

আমার জন্য, আপনার উদাহরণটি সুইফট ৩.০.১ এ কাজ করে না।

আমি খেলার মাঠে এই কোডটি প্রবেশ করলাম:

class Jedi {
    let lightsaberColor = "Blue"
}

class Sith: Jedi {
    override var lightsaberColor : String {
        return "Red"
    }
}

এক্সকোডে সংকলনের সময় ত্রুটি ফেলে:

অপরিবর্তনীয় 'সম্পত্তি' লাইটসবারার কালারকে 'ভার' এর সাথে পাওয়া যায় না

না, আপনি সঞ্চিত সম্পত্তির ধরণ পরিবর্তন করতে পারবেন না। Liskov উপকল্পন পুঁজি বাধ্য করে যে একটি উপশ্রেণী একটি জায়গা যেখানে সুপারক্লাস চেয়েছিলেন হয় ব্যবহার করা হয় অনুমতি আপনি।

তবে আপনি যদি এটিতে পরিবর্তন করেন var এবং সেইজন্য setগণনা করা সম্পত্তিতে যোগ করেন তবে আপনি একই ধরণের একটি গণিত সম্পত্তি দিয়ে সঞ্চিত সম্পত্তিটিকে ওভাররাইড করতে পারেন।

class Jedi {
    var lightsaberColor = "Blue"
}


class Sith: Jedi {
    override var lightsaberColor : String {
        get {
            return "Red"
        }
        set {
            // nothing, because only red is allowed
        }
    }
}

এটি সম্ভব কারণ এটি সঞ্চিত সম্পত্তি থেকে গণিত সম্পত্তিতে স্যুইচ করার অর্থ তৈরি করতে পারে।

তবে কোনও সঞ্চিত varসম্পত্তি সহ কোনও সঞ্চিত varসম্পত্তি ওভাররাইড করা কোনও অর্থবোধ করে না, কারণ আপনি কেবল সম্পত্তির মান পরিবর্তন করতে পারেন।

আপনি তবে কোনও সঞ্চিত সম্পত্তি সহ কোনও সঞ্চিত সম্পত্তিটিকে ওভাররাইড করতে পারবেন না।


আমি সিথ হ'ল জেডি :- পি। সুতরাং এটি পরিষ্কার যে এটি কাজ করতে পারে না।


18
class SomeClass {
    var hello = "hello"
}
class ChildClass: SomeClass {
    override var hello: String {
        set {
            super.hello = newValue
        }
        get {
            return super.hello
        }    
    }
}

13
যদিও এই কোড স্নিপেট একটি ব্যাখ্যা সহ প্রশ্নটি সমাধান করতে পারে, সত্যিই আপনার পোস্টের মান উন্নত করতে সহায়তা করে। মনে রাখবেন যে আপনি ভবিষ্যতে পাঠকদের জন্য প্রশ্নের উত্তর দিচ্ছেন, এবং সেই লোকেরা আপনার কোড পরামর্শের কারণগুলি জানেন না।
ডিমাসান

15

আপনি সম্ভবত সম্পত্তিটির জন্য অন্য একটি মান প্রদান করতে চান:

class Jedi {
    var lightSaberColor = "Blue"
}


class Sith: Jedi {
    override init() {
        super.init()
        self.lightSaberColor = "Red"
    }
}

9
উপরের মন্তব্য অনুসারে একই প্রযোজ্য
ম্যাক ম্যাকলিউড

10

অ্যাপল এর ডকুমেন্টেশন থেকে সুইফট 4 এর জন্য :

আপনি কোনও উত্তরাধিকার সূত্রে ওভাররাইড করতে পারেন বা সেই সম্পত্তিটির জন্য নিজস্ব নিজস্ব কাস্টম গেটার এবং সেটার সরবরাহ করতে সম্পত্তি টাইপ করতে পারেন, বা সম্পত্তি অন্তর্নিহিত সম্পত্তি মান পরিবর্তন হওয়ার পরে ওভাররাইডিং সম্পত্তিটি পর্যবেক্ষণ করতে সক্ষম করতে সম্পত্তি পর্যবেক্ষক যুক্ত করতে পারেন।


7

সুইফটে, দুর্ভাগ্যক্রমে এটি করা সম্ভব নয়। সর্বোত্তম বিকল্পটি হ'ল:

class Jedi {
    private(set) var lightsaberColor = "Blue"
}


class Sith: Jedi {
    override var lightsaberColor : String {
        get {
            return "Red"
        }
    }
}

3

ভিউ কন্ট্রোলারের জন্য ধ্রুবক সেট করতে আমার একই সমস্যা ছিল।

আমি যেমন চেহারাটি পরিচালনা করতে ইন্টারফেস বিল্ডার ব্যবহার করছি, আমি ব্যবহার করতে পারি না init(), সুতরাং আমার ভিত্তি অন্যান্য উত্তরগুলির সাথে সমান ছিল, আমি ব্যাস এবং উত্তরাধিকার সূত্রে প্রাপ্ত উভয় শ্রেণিতেই কেবল পঠনযোগ্য গণনা ভেরিয়েবল ব্যবহার করি।

class Jedi {
    var type: String {
        get { return "Blue" }
    }
}

class Sith: Jedi {
    override var type: String {
        get { return "Red" }
    }
}

3

আপনি যদি সুইফট 5 এ চেষ্টা করার চেষ্টা করেন তবে আপনাকে একটি দ্বারা অভ্যর্থনা জানানো হবে

স্থিতিশীল 'চলুন' সম্পত্তিটিকে 'লাইটস্যাবার কালার' এর সাথে 'ভার' সরবরাহকারীর সাথে ওভাররাইড করা যায় না

আপনার সেরা বাজি এটি একটি গণিত সম্পত্তি হিসাবে ঘোষণা করা।

এটি কেবলমাত্র get {}ফাংশনটিকে ওভাররাইড করে চলেছে বলেই এটি কাজ করে

class Base {
   var lightSaberColor: String { "base" }
}

class Red: Base {
   override var lightSaberColor: String { "red" }
}

2

stored propertyআপনি ব্যবহার করতে পারেন এর পরিবর্তে সুইফ্ট আপনাকে পরিবর্তনশীল ওভাররাইড করার অনুমতি দেয় নাcomputed property

class A {
    var property1 = "A: Stored Property 1"

    var property2: String {
        get {
            return "A: Computed Property 2"
        }
    }

    let property3 = "A: Constant Stored Property 3"

    //let can not be a computed property
    
    func foo() -> String {
        return "A: foo()"
    }
}

class B: A {

    //now it is a computed property
    override var property1: String {

        set { }
        get {
            return "B: overrode Stored Property 1"
        }
    }

    override var property2: String {
        get {
            return "B: overrode Computed Property 2"
        }
    }
    
    override func foo() -> String {
        return "B: foo()"
    }

    //let can not be overrode
}
func testPoly() {
    let a = A()
    
    XCTAssertEqual("A: Stored Property 1", a.property1)
    XCTAssertEqual("A: Computed Property 2", a.property2)
    
    XCTAssertEqual("A: foo()", a.foo())
    
    let b = B()
    XCTAssertEqual("B: overrode Stored Property 1", b.property1)
    XCTAssertEqual("B: overrode Computed Property 2", b.property2)
    
    XCTAssertEqual("B: foo()", b.foo())
    
    //B cast to A
    XCTAssertEqual("B: overrode Stored Property 1", (b as! A).property1)
    XCTAssertEqual("B: overrode Computed Property 2", (b as! A).property2)
    
    XCTAssertEqual("B: foo()", (b as! A).foo())
}

জাভার সাথে তুলনা করার সময় এটি আরও স্পষ্ট হয়, যেখানে কোনও শ্রেণি ক্ষেত্র ওভাররড করা যায় না এবং পলিমারফিজম সমর্থন করে না কারণ সংকলনের সময় (দক্ষতার সাথে চালানো) সংজ্ঞায়িত হয়। একে ভেরিয়েবল হিডিং বলা হয় [সম্পর্কে] এই প্রযুক্তিগুলি ব্যবহার করার পরামর্শ দেওয়া হয় না কারণ এটি পড়া / সমর্থন করা শক্ত

[পরিবর্তন সম্পত্তি]


1

ওভাররাইড করার জন্য আপনি কোনও ফাংশনও ব্যবহার করতে পারেন। এটি সরাসরি উত্তর নয়, তবে এই বিষয়টিকে সমৃদ্ধ করতে পারে)

শ্রেণীকক্ষে

override func viewDidLoad() {
    super.viewDidLoad()

    if shouldDoSmth() {
       // do
    }
}

public func shouldDoSmth() -> Bool {
    return true
}

ক্লাস বি: ক

public func shouldDoSmth() -> Bool {
    return false
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.