সুইফট ল্যাঙ্গুয়েজে বিমূর্ত ফাংশন


127

আমি দ্রুত ভাষায় একটি বিমূর্ত ফাংশন তৈরি করতে চাই। এটা কি সম্ভব?

class BaseClass {
    func abstractFunction() {
        // How do I force this function to be overridden?
    }
}

class SubClass : BaseClass {
    override func abstractFunction() {
        // Override
    }
}

এটি আপনার অন্যান্য প্রশ্নের খুব কাছাকাছি তবে এখানে উত্তরটি আরও ভাল বলে মনে হচ্ছে।
ডেভিড বেরি

প্রশ্নগুলি একই রকম তবে সমাধানগুলি অনেক আলাদা কারণ একটি বিমূর্ত শ্রেণীর একটি বিমূর্ত ফাংশনের চেয়ে আলাদা ব্যবহারের কেস রয়েছে।
কেভ

হ্যাঁ, আমি কেন বন্ধ করতে ভোট দিইনি, তবে উত্তরগুলি "আপনি পারবেন না" এর বাইরে কার্যকর হবে না এখানে আপনি সেরা উপলভ্য উত্তর পেয়েছেন :)
ডেভিড বেরি

উত্তর:


198

সুইফটে অ্যাবস্ট্রাক্টের কোনও ধারণা নেই (যেমন উদ্দেশ্য-সি) তবে আপনি এটি করতে পারেন:

class BaseClass {
    func abstractFunction() {
        preconditionFailure("This method must be overridden") 
    } 
}

class SubClass : BaseClass {
     override func abstractFunction() {
         // Override
     } 
}

13
বিকল্পভাবে আপনি ব্যবহার করতে পারেন assert(false, "This method must be overriden by the subclass")
এরিক

20
বাfatalError("This method must be overridden")
নাথান

5
যখন কোনও পদ্ধতিতে রিটার্নের ধরণ থাকে তখন দৃ as়তার সাথে রিটার্ন স্টেটমেন্টের প্রয়োজন হয়। আমি মনে করি এই এক কারণেই মারাত্মক ইরর () ভাল
অ্যান্ড্রে ফ্রেটেলি

6
এছাড়াও preconditionFailure("Bla bla bla")সুইফটে রয়েছে যা রিলিজ বিল্ডগুলিতে কার্যকর করবে এবং রিটার্নের বিবরণের প্রয়োজনীয়তাও দূর করবে। সম্পাদনা: শুধু জানতে পারলেন যে এই পদ্ধতি মূলত সমান fatalError()কিন্তু এটি আরো সঠিক উপায় (বেটার ডকুমেন্টেশন, সহ সুইফট চালু precondition(), assert()এবং assertionFailure()পড়তে এখানে )
Kametrixom

2
যদি ফাংশনটির রিটার্ন টাইপ থাকে তবে কী হবে?
লাভমিউ

36

আপনি যা চান তা বেস ক্লাস নয়, একটি প্রোটোকল।

protocol MyProtocol {
    func abstractFunction()
}

class MyClass : MyProtocol {
    func abstractFunction() {
    }
}

আপনি যদি আপনার ক্লাসে বিমূর্ত ফাংশন সরবরাহ না করেন তবে এটি একটি ত্রুটি।

আপনার যদি এখনও অন্য আচরণের জন্য বেসক্লাসের প্রয়োজন হয় তবে আপনি এটি করতে পারেন:

class MyClass : BaseClass, MyProtocol {
    func abstractFunction() {
    }
}

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

5
এটি আমার বক্তব্য .... বেসক্লাসের প্রোটোকলের সাথে কোনও সম্পর্ক নেই, এবং একটি বিমূর্ত শ্রেণীর মতো কাজ করার জন্য এটির সাথে কিছু করা উচিত। আমি কী লিখেছি তা স্পষ্ট করার জন্য "যদি বেসক্লাস এই শূন্য ফাংশনগুলি কল করতে চায়, তবে এটি এমন প্রোটোকলও প্রয়োগ করতে হবে যা আপনাকে ফাংশনগুলি প্রয়োগ করতে বাধ্য করবে - যার ফলে সাবক্লাসটি সংকলনের সময় ফাংশনগুলি প্রয়োগ করতে বাধ্য করা হবে না, কারণ বেসক্লাস ইতিমধ্যে এটি সম্পন্ন করেছে "।
বান্দেজপাটাইস

4
এটি সত্যই নির্ভর করে আপনি কীভাবে "বিমূর্ত" সংজ্ঞা দেন। বিমূর্ত ফাংশনটির পুরো বিষয়টি হ'ল আপনি এটিকে এমন কোনও শ্রেণিতে রাখতে পারেন যা সাধারণ বর্গ জিনিস করতে পারে। উদাহরণস্বরূপ, আমি এটির কারণটি হ'ল কারণ আমার একটি স্থির সদস্যকে সংজ্ঞায়িত করা দরকার যা আপনি প্রোটোকলের সাহায্যে করতে পারেন না। সুতরাং এটি আমার পক্ষে কঠিন যে এটি একটি বিমূর্ত ফাংশনটির দরকারী পয়েন্টটি পূরণ করে।
কুকুরছানা

3
আমি মনে করি উপরোক্ত আপত্তিযুক্ত মন্তব্যগুলির সাথে উদ্বেগটি হ'ল এটি লিসকভ সাবস্টিটিউশন নীতিটির সাথে খাপ খায় না যা বলে যে "একটি প্রোগ্রামের বিষয়গুলিকে সেই প্রোগ্রামের যথার্থতা পরিবর্তন না করে তাদের সাব-টাইপের উদাহরণ সহ প্রতিস্থাপনযোগ্য হওয়া উচিত।" ধারণা করা হচ্ছে এটি একটি বিমূর্ত প্রকার। এটি বিশেষত কারখানার পদ্ধতি প্যাটার্নের ক্ষেত্রে গুরুত্বপূর্ণ যেখানে উপ শ্রেণী থেকে উদ্ভূত বৈশিষ্ট্য তৈরি এবং সংরক্ষণের জন্য বেস শ্রেণি দায়বদ্ধ।
ডেভিড জেমস

2
একটি বিমূর্ত বেস ক্লাস এবং একটি প্রোটোকল একই জিনিস নয়।
শোয়েব

29

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

সুইফটে এটি করার জন্য আপনার একটি প্রোটোকল এবং একটি বেস ক্লাস প্রয়োজন।

protocol Thing
{
    func sharedFunction()
    func abstractFunction()
}

class BaseThing
{
    func sharedFunction()
    {
        println("All classes share this implementation")
    }
}

নোট করুন যে বেস ক্লাসটি ভাগ করা পদ্ধতি (গুলি) প্রয়োগ করে তবে প্রোটোকলটি কার্যকর করে না (যেহেতু এটি সমস্ত পদ্ধতি প্রয়োগ করে না)।

তারপরে উত্পন্ন শ্রেণিতে:

class DerivedThing : BaseThing, Thing 
{
    func abstractFunction() 
    {
        println("Derived classes implement this");
    }
}

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

এই পদ্ধতির একমাত্র আসল ক্ষতি হ'ল যেহেতু বেস ক্লাসটি প্রোটোকলটি বাস্তবায়ন করে না, আপনার যদি একটি বেস ক্লাস পদ্ধতি থাকে যাতে প্রোটোকল সম্পত্তি / পদ্ধতিতে অ্যাক্সেসের প্রয়োজন হয় তবে আপনাকে সেই উত্স থেকে প্রাপ্ত ক্লাসে ওভাররাইড করতে হবে, এবং সেখান থেকে কল করুন বেস ক্লাসটি (সুপারের মাধ্যমে) পাশ করা হয় selfযাতে বেস ক্লাসটির প্রোটোকলের একটি উদাহরণ থাকে যার সাহায্যে এটি কাজ করতে পারে।

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

class BaseThing
{
    func sharedFunction(thing: Thing)
    {
        println("All classes share this implementation")
        thing.abstractFunction()
    }
}

class DerivedThing : BaseThing, Thing 
{
    func sharedFunction()
    {
        super.sharedFunction(self)
    }

    func abstractFunction() 
    {
        println("Derived classes implement this");
    }
}

এখন উত্পন্ন শ্রেণীর ভাগ করা ফাংশন প্রোটোকলের সেই অংশটি সন্তুষ্ট করছে, তবে উত্পন্ন শ্রেণিটি এখনও বেস শ্রেণীর যুক্তি যুক্তিসঙ্গত সোজা উপায়ে ভাগ করতে সক্ষম।


4
"বেস ক্লাস প্রোটোকল বাস্তবায়ন করে না" ... সম্পর্কে দুর্দান্ত বোঝাপড়া এবং ভাল গভীরতা ... এটি একটি বিমূর্ত শ্রেণীর বিন্দুর মতো। আমি অবাক হয়েছি যে এই প্রাথমিক OO বৈশিষ্ট্যটি অনুপস্থিত, তবে আবার আমি জাভাতে উত্থাপিত হয়েছিল।
ড্যান রোজনস্টার্ক

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

1
"সুরক্ষিত" কীওয়ার্ডটি প্রবর্তন করে এত বেশি সময় এবং কোড সংরক্ষণ করা যায়।
শোয়েব

23

অ্যাপল ইউআইকিটিতে কীভাবে বিমূর্ত পদ্ধতি পরিচালনা করছে এটি এই "অফিসিয়াল" উপায় বলে মনে হচ্ছে। UITableViewControllerএটি কীভাবে কাজ করছে তা একবার দেখুন UITableViewDelegate। প্রথম জিনিস আপনি কি এক, একটি লাইন যোগ করা: delegate = self। ঠিক আছে, এটি ঠিক কৌশল।

1. বিমূর্ত পদ্ধতিটি একটি প্রোটোকলে রাখুন
protocol AbstractMethodsForClassX {
    func abstractMethod() -> String
}
2. আপনার বেস ক্লাস লিখুন
/// It takes an implementation of the protocol as property (same like the delegate in UITableViewController does)
/// And does not implement the protocol as it does not implement the abstract methods. It has the abstract methods available in the `delegate`
class BaseClassX {
    var delegate: AbstractMethodsForClassX!

    func doSomethingWithAbstractMethod() -> String {
        return delegate.abstractMethod() + " - And I believe it"
    }
}
3. সাবক্লাস (এস) লিখুন।
/// First and only additional thing you have to do, you must set the "delegate" property
class ClassX: BaseClassX, AbstractMethodsForClassX {
    override init() {
        super.init()
        delegate = self
    }

    func abstractMethod() -> String {return "Yes, this works!"}
}
এখানে আপনি কীভাবে সমস্ত ব্যবহার করবেন তা এখানে
let x = ClassX()
x.doSomethingWithAbstractMethod()

আউটপুট দেখতে খেলার মাঠের সাথে চেক করুন।

কিছু মন্তব্য

  • প্রথমত, ইতিমধ্যে প্রচুর উত্তর দেওয়া হয়েছিল। আমি আশা করি যে কেউ এই পথে নেমেছে।
  • প্রশ্নটি আসলে ছিল এমন একটি প্যাটার্নটি সন্ধান করতে:
    • একটি শ্রেণি একটি পদ্ধতি কল করে, এটি তার উত্পন্ন সাবক্লাসগুলির একটিতে প্রয়োগ করা উচিত (ওভাররাইড)
    • সর্বোত্তম ক্ষেত্রে, যদি পদ্ধতিটি সাবক্লাসে ওভাররাইড করা না হয় তবে সংকলনের সময় একটি ত্রুটি পান
  • বিমূর্ত পদ্ধতি সম্পর্কে জিনিসটি হ'ল, এগুলি হ'ল একটি ইন্টারফেস সংজ্ঞা এবং বেস শ্রেণিতে প্রকৃত বাস্তবায়নের অংশ। উভয় একই সময়ে। যেহেতু সুইফ্টটি খুব নতুন এবং খুব পরিষ্কার সংজ্ঞায়িত, এটির মতো কোনও পরিচ্ছন্নতা নেই "অশুচি" ধারণা (এখনও)।
  • আমার কাছে (একজন দরিদ্র পুরানো জাভা লোক), সময়ে সময়ে এই সমস্যাটি বিকশিত হয়। আমি এই পোস্টে সমস্ত উত্তর দিয়ে পড়েছি এবং এবার আমি মনে করি যে আমি একটি প্যাটার্ন পেয়েছি, এটি সম্ভবত কার্যকর - কমপক্ষে আমার কাছে।
  • আপডেট : দেখে মনে হচ্ছে অ্যাপেলের ইউআইকিট প্রয়োগকারীরা একই প্যাটার্নটি ব্যবহার করেন। UITableViewControllerপ্রয়োগগুলি রয়েছে UITableViewDelegateতবে স্বচ্ছভাবে delegateসম্পত্তি সেট করে প্রতিনিধি হিসাবে নিবন্ধিত হওয়া দরকার ।
  • এই সমস্তটি Xcode 7.3.1 এর খেলার মাঠে পরীক্ষা করা হয় tested

সম্ভবত নিখুঁত নয়, কারণ ক্লাসের ইন্টারফেসটি অন্য ক্লাস থেকে আড়াল করতে আমার সমস্যা আছে, তবে সুইফটে ক্লাসিক ফ্যাক্টরি পদ্ধতিটি প্রয়োগ করার জন্য আমার যা প্রয়োজন তা যথেষ্ট।
টমাসজ নাজারেঙ্কো

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

সুতরাং আমার getCommentsপিতামাতার প্রতিনিধি সম্পর্কে একটি পদ্ধতি আছে । মুষ্টিমেয় মন্তব্যের ধরণ রয়েছে এবং আমি প্রতিটি বস্তুর সাথে প্রাসঙ্গিক চাই। সুতরাং, আমি চাই যে আমি যখন delegate.getComments()এই পদ্ধতিটি ওভাররাইড না করি তখন সাবক্লাসগুলি সংকলন না করে do ভিসি কেবলমাত্র এটি জানেন যে এটির একটি ParentDelegateবস্তু বলা হয়েছে delegate, বা BaseClassXআপনার উদাহরণে, তবে BaseClassXবিমূর্ত পদ্ধতিটি নেই। আমি ভিসি বিশেষভাবে এটি ব্যবহার করে তা জানতে প্রয়োজন SubclassedDelegate
জ্যাক টি।

আমি আশা করি আমি আপনাকে ঠিক বুঝতে পেরেছি। যদি তা না হয় তবে আপনি একটি নতুন প্রশ্ন জিজ্ঞাসা করতে আপত্তি করছেন যেখানে আপনি কিছু কোড যুক্ত করতে পারেন? আমি মনে করি আপনার যদি ডেলিগেট সেট করা থাকে বা না থাকে তবে ‚doSomeomingWithAbstractMethod 'চেকিংয়ে আপনার কেবল একটি বিবৃতি থাকা দরকার।
jboi

এটি উল্লেখ করার মতো বিষয় যে ডেলিগেটকে নিজেকে অর্পণ করা একটি বজায় রাখা চক্র তৈরি করে। সম্ভবত এটিকে দুর্বল হিসাবে ঘোষণা করা ভাল (যা সাধারণত প্রতিনিধিদের পক্ষে ভাল ধারণা)
এনরিকোজা

7

এটি করার একটি উপায় হ'ল বেস ক্লাসে সংজ্ঞায়িত alচ্ছিক ক্লোজার ব্যবহার করা এবং বাচ্চারা এটি প্রয়োগ করতে বা না বেছে নিতে পারে।

class BaseClass {
    var abstractClosure?:(()->())?
    func someFunc()
    {
        if let abstractClosure=abstractClosure
        {
            abstractClosure()
        }
    } 
}

class SubClass : BaseClass {
    init()
    {
        super.init()
        abstractClosure={ ..... }
    }
}

এই পদ্ধতির সম্পর্কে আমি যা পছন্দ করি তা হ'ল উত্তরাধিকার সূত্রে প্রাপ্ত শ্রেণিতে কোনও প্রোটোকল প্রয়োগ করার কথা মনে রাখার দরকার নেই। আমার ভিউকন্ট্রোলারদের জন্য আমার একটি বেস ক্লাস রয়েছে এবং আমি এভাবেই ভিউকন্ট্রোলার নির্দিষ্ট, alচ্ছিক কার্যকারিতা (যেমন অ্যাপ্লিকেশন সক্রিয় হয়ে ওঠে) প্রয়োগ করি যা বেস ক্লাসের কার্যকারিতা দ্বারা প্রেরণা পেতে পারে।
প্রোগ্রামমিয়ারটাইয়ার

6

ঠিক আছে, আমি জানি যে আমি খেলায় দেরি করেছি এবং আমি সম্ভবত যে পরিবর্তনগুলি করেছি তার সুযোগ নিয়েছি। এর জন্যে দুঃখিত.

যাই হোক না কেন, আমি আমার উত্তরটি অবদান রাখতে চাই, কারণ আমি টেস্টিং এবং এর সমাধানগুলি করতে পছন্দ করি fatalError() হ'ল, আফাইক, নয় এবং ব্যতিক্রমগুলির সাথে পরীক্ষা করা আরও শক্ত।

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

একটি কংক্রিট ফাংশন দিয়ে আপনার উদাহরণকে প্রসারিত করা:

protocol BaseAbstraction {
    func abstractFunction() {
        // How do I force this function to be overridden?
    }
}

extension BaseAbstraction {
    func definedFunction() {
        print("Hello")
}

class SubClass : BaseAbstraction {
    func abstractFunction() {
        // No need to "Override". Just implement.
    }
}

লক্ষ্য করুন যে এটি করে, সংকলকটি আবার আপনার বন্ধু। যদি পদ্ধতিটি "ওভাররাইড" না হয় তবে আপনি সংকলনের সময় একটি ত্রুটি পেয়ে যাবেন যা আপনি পেয়ে যাবেন তার পরিবর্তে fatalError()বা রান সময়ে ঘটে যাওয়া ব্যতিক্রমগুলি।


1
ইমো সেরা উত্তর।
অ্যাপফেলস্যাফ্ট

1
উত্তম উত্তর, তবে আপনার বেস অ্যাবস্ট্রাকশন তবে বৈশিষ্ট্যগুলি সঞ্চয় করতে সক্ষম নয়
জোহিংকল 11

5

আপনি এখন কী করছেন তা আমি বুঝতে পেরেছি, আমি মনে করি আপনি একটি প্রোটোকল ব্যবহার করা ভাল better

protocol BaseProtocol {
    func abstractFunction()
}

তারপরে, আপনি কেবল প্রোটোকল অনুসারে:

class SubClass : BaseProtocol {

    func abstractFunction() {
        // Override
        println("Override")
    }
}

আপনি যদি শ্রেণিটিও একটি সাবক্লাস হন তবে প্রোটোকলগুলি সুপারক্লাসটি অনুসরণ করে:

class SubClass: SuperClass, ProtocolOne, ProtocolTwo {}

3

assertবিমূর্ত পদ্ধতি প্রয়োগের জন্য কীওয়ার্ড ব্যবহার করা :

class Abstract
{
    func doWork()
    {
        assert(false, "This method must be overriden by the subclass")
    }
}

class Concrete : Abstract
{
    override func doWork()
    {
        println("Did some work!")
    }
}

let abstract = Abstract()
let concrete = Concrete()

abstract.doWork()    // fails
concrete.doWork()    // OK

তবে, স্টিভ ওয়াডিকর যেমন উল্লেখ করেছেন আপনি সম্ভবত এর protocolপরিবর্তে চান ।


বিমূর্ত পদ্ধতিগুলির সুবিধা হ'ল চেকগুলি সংকলনের সময় করা হয়।
ফ্যাবরিজিও বার্টোলোমুচি

দৃ use়তা ব্যবহার করবেন না, কারণ সংরক্ষণাগার নেওয়ার সময়, আপনি 'ফাংশনটিতে প্রত্যাশিত প্রত্যাবর্তন প্রত্যাশিত' ত্রুটি পাবেন। ফ্যাটালআরার ব্যবহার করুন ("এই পদ্ধতিটি অবশ্যই সাবক্লাসের দ্বারা ওভার্রাইড করা উচিত")
জাপোরোজচেনকো ওলেকসান্ডার

2

আমি প্রশ্নটি বুঝতে পেরেছি এবং একই সমাধানের সন্ধান করছি। প্রোটোকলগুলি অ্যাবস্ট্রাক্ট পদ্ধতির মতো নয়।

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

অন্য কথায়, প্রোটোকলগুলি একধরণের বিকল্প,

অ্যাবস্ট্রাক্ট পদ্ধতির মানে হল যে আপনি একটি বেস ক্লাস চান তবে আপনার নিজের বা দুটি পদ্ধতি প্রয়োগ করতে হবে যা একই নয়।

আমারও একই আচরণের প্রয়োজন, সে কারণেই আমি একটি সমাধান খুঁজছিলাম। আমার ধারণা স্যুইফ্ট এ জাতীয় বৈশিষ্ট্যটি অনুপস্থিত।


1

এই ইস্যুটির আরও একটি বিকল্প আছে, যদিও @ জৌমার্ডের প্রস্তাবের তুলনায় এখনও একটি খারাপ দিক রয়েছে; এটির জন্য একটি বিবৃতি বিবরণ প্রয়োজন। যদিও আমি এটির প্রয়োজনের বিষয়টিটি মিস করি, কারণ এটি সরাসরি একটি ব্যতিক্রম ছুঁড়ে ফেলার অন্তর্ভুক্ত:

class AbstractMethodException : NSException {

    init() {
        super.init(
            name: "Called an abstract method",
            reason: "All abstract methods must be overriden by subclasses",
            userInfo: nil
        );
    }
}

এবং তারপর:

class BaseClass {
    func abstractFunction() {
        AbstractMethodException.raise();
    }
}

এর পরে যা কিছু আসে তা অ্যাক্সেসযোগ্য, তাই আমি কেন ফিরে আসার জন্য জোর করব তা দেখছি না।


মানে AbstractMethodException().raise()?
জোশকড 21

এর ... সম্ভবত। আমি এখনই পরীক্ষা করতে পারছি না, তবে এটি যদি হ্যাঁ এর চেয়ে
ভালভাবে

1

আমি জানি না এটি কার্যকর হতে চলেছে, তবে স্প্রিটকিট গেমটি তৈরির চেষ্টা করার সময় আমার বিমূর্ত পদ্ধতিতে একই রকম সমস্যা ছিল। আমি যা চেয়েছিলাম তা হ'ল একটি বিমূর্ত প্রাণী শ্রেণীর মুভ (), রান () ইত্যাদির মতো পদ্ধতি রয়েছে তবে স্প্রাইটের নাম (এবং অন্যান্য কার্যকারিতা) ক্লাসের শিশুদের দ্বারা সরবরাহ করা উচিত। সুতরাং আমি এই জাতীয় কিছু করে শেষ করেছি (সুইফ্ট 2 এর জন্য পরীক্ষিত):

import SpriteKit

// --- Functions that must be implemented by child of Animal
public protocol InheritedAnimal
{
    func walkSpriteNames() -> [String]
    func runSpriteNames() -> [String]
}


// --- Abstract animal
public class Animal: SKNode
{
    private let inheritedAnimal: InheritedAnimal

    public init(inheritedAnimal: InheritedAnimal)
    {
        self.inheritedAnimal = inheritedAnimal
        super.init()
    }

    public required init?(coder aDecoder: NSCoder)
    {
        fatalError("NSCoding not supported")
    }

    public func walk()
    {
        let sprites = inheritedAnimal.walkSpriteNames()
        // create animation with walking sprites...
    }

    public func run()
    {
        let sprites = inheritedAnimal.runSpriteNames()
        // create animation with running sprites
    }
}


// --- Sheep
public class SheepAnimal: Animal
{
    public required init?(coder aDecoder: NSCoder)
    {
        fatalError("NSCoding not supported")
    }

    public required init()
    {
        super.init(inheritedAnimal: InheritedAnimalImpl())
    }

    private class InheritedAnimalImpl: InheritedAnimal
    {
        init() {}

        func walkSpriteNames() -> [String]
        {
            return ["sheep_step_01", "sheep_step_02", "sheep_step_03", "sheep_step_04"]
        }

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