স্টিফ্ট ফানক এবং সুইফটে ক্লাস ফানকের মধ্যে পার্থক্য কী?


334

আমি সুইফট লাইব্রেরিতে এই সংজ্ঞাগুলি দেখতে পাচ্ছি:

extension Bool : BooleanLiteralConvertible {
    static func convertFromBooleanLiteral(value: Bool) -> Bool
}

protocol BooleanLiteralConvertible {
    typealias BooleanLiteralType
    class func convertFromBooleanLiteral(value: BooleanLiteralType) -> Self
}

হিসাবে সংজ্ঞায়িত সদস্য ফাংশন static funcএবং অন্য একটি হিসাবে পার্থক্য কি class func? এটি কি কেবল staticস্ট্রাক্ট এবং এনামগুলির স্ট্যাটিক ফাংশন এবং classক্লাস এবং প্রোটোকলের জন্য? অন্য কোন পার্থক্য আছে যা সম্পর্কে জানা উচিত? বাক্যবিন্যাসের মধ্যেই এই পার্থক্য থাকার যুক্তি কী?


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

2
বোনাস প্রশ্ন, তারপরে: কোনও কাঠামো একটি প্রোটোকলের সাথে সংযুক্ত হতে পারে যা একটি সংজ্ঞা দেয় class func? আমাদের কাছে থাকা তথ্যের সাথে, এই পার্থক্যটি বরং অকেজো বলে মনে হচ্ছে, তাই না?
জিন-ফিলিপ পেলিট

3
হ্যা, তুমি পারো. অদ্ভুত তাই না?
ফেব্রাইস ট্রুইলোট ডি চ্যাম্বিয়ার

7
অপ্রতিরোধ্য পার্থক্য হ'ল আপনি class funcগুলি ওভারাইড করতে পারেন
ফ্যাটি

1
বিবেচনা করা হবে:error: class methods are only allowed within classes; use 'static' to declare a static method
গ্যাব্রিয়েল গনক্যাল্ভস

উত্তর:


238

স্ট্যাটিক স্ট্রাক্ট এবং এনামগুলির স্ট্যাটিক ফাংশন এবং ক্লাস এবং প্রোটোকলের জন্য ক্লাসের জন্য কি কেবল সহজ?

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

প্রোটোকলগুলি শ্রেণিবদ্ধ কীওয়ার্ড ব্যবহার করে তবে প্রোটোকল প্রয়োগ থেকে স্ট্রিটগুলি বাদ দেয় না, তারা কেবল পরিবর্তে স্থির ব্যবহার করে। প্রোটোকলের জন্য ক্লাসটি বেছে নেওয়া হয়েছিল সুতরাং স্থির বা শ্রেণীর প্রতিনিধিত্ব করার জন্য কোনও তৃতীয় কীওয়ার্ডের প্রয়োজন হবে না।

এই বিষয়ে ক্রিস ল্যাটনার থেকে:

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

এবং এখানে একটি স্নিপেট যা শ্রেণীর ফাংশনগুলির কিছু ওভাররাইড আচরণ দেখায়:

class MyClass {
    class func myFunc() {
        println("myClass")
    }
}

class MyOtherClass: MyClass {
    override class func myFunc() {
        println("myOtherClass")
    }
}

var x: MyClass = MyOtherClass()
x.dynamicType.myFunc() //myOtherClass
x = MyClass()
x.dynamicType.myFunc() //myClass

4
আহা, ক্লাস ফাংশনগুলি গতিশীলভাবে প্রেরণ করা হয় যে খুব গুরুত্বপূর্ণ পয়েন্ট! কিন্তু আপনি যেমন একটি উদাহরণ দিতে পারে? আপনার ক্লাসের নাম কোথাও লিখতে হবে, তাই না? তাহলে স্ট্যাটিকালি কেন stat শ্রেণির প্রয়োগকে বেছে নিচ্ছেন না?
জিন-ফিলিপ পেলিট

1
আর একটি পরিপূরক প্রশ্ন: কোথা থেকে উদ্ধৃতিটি আপনি পেয়েছেন?
জিন-ফিলিপ পেলিট

আমার বোধগম্যতা হ'ল শ্রেণীর ফাংশনগুলি হুডের অধীনে অবজেক্ট + পদ্ধতিগুলির মতো প্রায় একই কাজ করে
কনর

1
আমি কি এখানে একটি সহজ উত্তর লিঙ্ক সরবরাহ করতে পারি? stackoverflow.com/questions/29636633/...
allenlinli

1
@ জিন-ফিলিপেললেট উপরের উদাহরণে ... আপনি যদি এর static func myFunc()পরিবর্তে ব্যবহার করেন class func myFuncতবে নীচের ত্রুটি পাবেন l: স্থির পদ্ধতিটিকে ওভাররাইড করতে পারে না । কেন? কারণ এটি যেমন এটি চিহ্নিত করা হয়েছে final। আরও তথ্যের জন্য. নীচে NextD এর উত্তর দেখুন। এছাড়াও x.dynamicTypeএখন প্রতিস্থাপন করা হয়েছেtype(of:x)
মধু

246

আরও পরিষ্কার করে বলতে গেলে, আমি এখানে একটি উদাহরণ দিচ্ছি,

class ClassA {
  class func func1() -> String {
    return "func1"
  }

  static func func2() -> String {
    return "func2"
  }

  /* same as above
  final class func func2() -> String {
    return "func2"
  }
  */
}

static func হিসাবে একই final class func

কারণ এটি final, আমরা এটি নীচের মতো সাবক্লাসে ওভাররাইড করতে পারি না:

class ClassB : ClassA {
  override class func func1() -> String {
    return "func1 in ClassB"
  }

  // ERROR: Class method overrides a 'final` class method
  override static func func2() -> String {
    return "func2 in ClassB"
  }
}

18
আপনি চ্যাম্প, দুর্দান্ত উত্তর .. আমি এই ভিন্নতা খুঁজছিলাম .. জ্যাক !!
অভিমন্যু রাঠোর

5
পারফেক্ট। চিত্তাকর্ষক।
মেহুল

5
এটি সঠিক উত্তর হিসাবে চিহ্নিত করা উচিত। পরিষ্কার এবং পরিচ্ছন্ন!
abhinavroy23

1
সেরা ব্যাখ্যা! এটি আমাকে আরও একটি সন্দেহের দিকে নিয়ে যায়। 'ক্লাস ফানক' ব্যবহারের কোনও স্পষ্ট কারণ আছে কি? মানে আপনি যদি কেবল 'ফানক' ব্যবহার করেন তবে এটি একইভাবে ওভাররাইড করা যেতে পারে, তবে পার্থক্য কী?
মার্কোস রেবুকাস

1
@ মারকোস রেবুকাস যদি আমি আপনার প্রশ্নটি সঠিকভাবে বুঝতে পারি তবে তা class funcস্বাভাবিক থেকে আলাদা funcযদিও উভয়ই ওভাররাইড করা যেতে পারে। তবে funcএটি একটি উদাহরণ / অবজেক্টের জন্য এবং class funcশ্রেণীর মাধ্যমে অ্যাক্সেস করা যায়ClassA.classFunc()
জ্যাক লিন

78

আমি খেলার মাঠে কিছু পরীক্ষা-নিরীক্ষা করেছি এবং কিছু উপসংহার পেয়েছি।

টি এল; ডিআর এখানে চিত্র বর্ণনা লিখুন

আপনি দেখতে পাচ্ছেন, ক্ষেত্রে class, ব্যবহার class funcবা ব্যবহার static funcকরা কেবল অভ্যাসের প্রশ্ন।

ব্যাখ্যার সাথে খেলার মাঠের উদাহরণ:

class Dog {
    final func identity() -> String {
        return "Once a woofer, forever a woofer!"
    }

    class func talk() -> String {
        return "Woof woof!"
    }

    static func eat() -> String {
        return "Miam miam"
    }

    func sleep() -> String {
        return "Zzz"
    }
}

class Bulldog: Dog {
    // Can not override a final function
//    override final func identity() -> String {
//        return "I'm once a dog but now I'm a cat"
//    }

    // Can not override a "class func", but redeclare is ok
    func talk() -> String {
        return "I'm a bulldog, and I don't woof."
    }

    // Same as "class func"
    func eat() -> String {
        return "I'm a bulldog, and I don't eat."
    }

    // Normal function can be overridden
    override func sleep() -> String {
        return "I'm a bulldog, and I don't sleep."
    }
}

let dog = Dog()
let bullDog = Bulldog()

// FINAL FUNC
//print(Dog.identity()) // compile error
print(dog.identity()) // print "Once a woofer, forever a woofer!"
//print(Bulldog.identity()) // compile error
print(bullDog.identity()) // print "Once a woofer, forever a woofer!"

// => "final func" is just a "normal" one but prevented to be overridden nor redeclared by subclasses.


// CLASS FUNC
print(Dog.talk()) // print "Woof woof!", called directly from class
//print(dog.talk()) // compile error cause "class func" is meant to be called directly from class, not an instance.
print(Bulldog.talk()) // print "Woof woof!" cause it's called from Bulldog class, not bullDog instance.
print(bullDog.talk()) // print "I'm a bulldog, and I don't woof." cause talk() is redeclared and it's called from bullDig instance

// => "class func" is like a "static" one, must be called directly from class or subclassed, can be redeclared but NOT meant to be overridden.

// STATIC FUNC
print(Dog.eat()) // print "Miam miam"
//print(dog.eat()) // compile error cause "static func" is type method
print(Bulldog.eat()) // print "Miam miam"
print(bullDog.eat()) // print "I'm a bulldog, and I don't eat."

// NORMAL FUNC
//print(Dog.sleep()) // compile error
print(dog.sleep()) // print "Zzz"
//print(Bulldog.sleep()) // compile error
print(bullDog.sleep()) // print "I'm a bulldog, and I don't sleep."

7
আপনার উদাহরণগুলি অন্য উত্তরের মূল পার্থক্য হিসাবে উল্লেখ করা কেসটি কভার করে না: classফাংশনগুলির গতিশীল প্রেরণ বনাম স্থির বাইন্ডিং static
জিন-ফিলিপ পেলেট

1
ফাংশন বোঝার জন্য দুর্দান্ত ব্যাখ্যা।
ইউসুল বায়রাম

33
class funcওভাররিডেবল না ?
আইলিয়ান ওনোফ্রেই

9
আপনি যদি কোনও স্থিতিশীল পদ্ধতিকে ওভাররাইড করার চেষ্টা করেন তবে আপনি কোনও ত্রুটি পাবেন। তবে আপনি একটি শ্রেণিবদ্ধ পদ্ধতিতে ওভাররাইড করতে পারেন । গৃহীত উত্তরটি দেখুন
মধু

8
class funcওভাররিডেবল। আমি এটিকে অন্যথায় ভোট দিতাম; গবেষণা এবং উদাহরণ ভালবাসা!
বেন লেগিগেরো

52

কোনও প্রকারের পরিবর্তনশীল সম্পত্তি ঘোষণা করতে, staticঘোষণাপত্রটি সংশোধনকারীকে চিহ্নিত করুন । ক্লাসগুলি classসাবক্লাসগুলিকে সুপারক্লাসের প্রয়োগকে ওভাররাইড করার জন্য পরিবর্তে ঘোষণাপত্র সংশোধকটির সাথে সংযুক্ত বৈশিষ্ট্যগুলি চিহ্নিত করতে পারে । প্রকার বৈশিষ্ট্য প্রকারভেদে আলোচনা করা হয় discussed

দ্রষ্টব্য
একটি শ্রেণীর ঘোষণায়, কীওয়ার্ডের staticসাথে ঘোষণাকে উভয় classএবং finalঘোষণাপত্রের সংশোধনকারীকে চিহ্নিত করার মতোই প্রভাব রয়েছে ।

উত্স: দ্য সুইফ্ট প্রোগ্রামিং ল্যাঙ্গুয়েজ - টাইপ ভেরিয়েবল প্রোপার্টি


5
প্রশ্নটি 'স্ট্যাটিক ফানক' এবং 'ক্লাস ফানক' সম্পর্কে জিজ্ঞাসা করছে। এটি টাইপ প্রোপার্টি সম্পর্কে জিজ্ঞাসা করছে না। সুতরাং এটি প্রশ্নের উত্তর দেয় না - যদিও সম্পত্তি হিসাবেও এই কীওয়ার্ডগুলির প্রসঙ্গটি বোঝা গুরুত্বপূর্ণ।
এটাইলুজ

এই উত্তরটি কেবল ভুল প্রশ্নে রয়েছে, সম্ভবত এটি এখানে দুর্ঘটনাক্রমে পোস্ট করা হয়েছিল?
ফ্যাটি

15

আপেল দ্বারা প্রকাশিত সুইফট ২.২ বই অনুসারে:

“আপনি পদ্ধতির staticফানক কীওয়ার্ডের আগে কীওয়ার্ডটি লিখে টাইপ পদ্ধতিগুলি নির্দেশ করেন । ক্লাসগুলি সাবক্লাসগুলি সেই পদ্ধতির সুপারক্লাসের প্রয়োগকে ওভাররাইড করার অনুমতি দেওয়ার জন্য classকীওয়ার্ডটিও ব্যবহার করতে পারে । "


10

সুইফট ২.০ থেকে অ্যাপল বলেছেন:

"আপনি যখন প্রোটোকলটিতে সংজ্ঞায়িত করেন তখন স্থির কীওয়ার্ড সহ সর্বদা প্রিফিক্স ধরণের সম্পত্তির প্রয়োজনীয়তাগুলি থাকে।


4

এই উদাহরণটি প্রতিটি দিক পরিষ্কার করবে!

import UIKit

class Parent {
    final func finalFunc() -> String { // Final Function, cannot be redeclared.
        return "Parent Final Function."
    }

    static func staticFunc() -> String { // Static Function, can be redeclared.
        return "Parent Static Function."
    }

    func staticFunc() -> String { // Above function redeclared as Normal function.
        return "Parent Static Function, redeclared with same name but as non-static(normal) function."
    }

    class func classFunc() -> String { // Class Function, can be redeclared.
        return "Parent Class Function."
    }

    func classFunc() -> String { // Above function redeclared as Normal function.
        return "Parent Class Function, redeclared with same name but as non-class(normal) function."
    }

    func normalFunc() -> String { // Normal function, obviously cannot be redeclared.
        return "Parent Normal Function."
    }
}

class Child:Parent {

    // Final functions cannot be overridden.

    override func staticFunc() -> String { // This override form is of the redeclared version i.e: "func staticFunc()" so just like any other function of normal type, it can be overridden.
        return "Child Static Function redeclared and overridden, can simply be called Child Normal Function."
    }

    override class func classFunc() -> String { // Class function, can be overidden.
        return "Child Class Function."
    }

    override func classFunc() -> String { // This override form is of the redeclared version i.e: "func classFunc()" so just like any other function of normal type, it can be overridden.
        return "Child Class Function, redeclared and overridden, can simply be called Child Normal Function."
    }

    override func normalFunc() -> String { // Normal function, can be overridden.
        return "Child Normal Function."
    }
}

let parent = Parent()
let child = Child()

// Final
print("1. " + parent.finalFunc())   // 1. Can be called by object.
print("2. " + child.finalFunc())    // 2. Can be called by object, parent(final) function will be called.
// Parent.finalFunc()               // Cannot be called by class name directly.
// Child.finalFunc()                // Cannot be called by class name directly.

// Static
print("3. " + parent.staticFunc())  // 3. Cannot be called by object, this is redeclared version (i.e: a normal function).
print("4. " + child.staticFunc())   // 4. Cannot be called by object, this is override form redeclared version (normal function).
print("5. " + Parent.staticFunc())  // 5. Can be called by class name directly.
print("6. " + Child.staticFunc())   // 6. Can be called by class name direcly, parent(static) function will be called.

// Class
print("7. " + parent.classFunc())   // 7. Cannot be called by object, this is redeclared version (i.e: a normal function).
print("8. " + child.classFunc())    // 8. Cannot be called by object, this is override form redeclared version (normal function).
print("9. " + Parent.classFunc())   // 9. Can be called by class name directly.
print("10. " + Child.classFunc())   // 10. Can be called by class name direcly, child(class) function will be called.

// Normal
print("11. " + parent.normalFunc())  // 11. Can be called by object.
print("12. " + child.normalFunc())   // 12. Can be called by object, child(normal) function will be called.
// Parent.normalFunc()               // Cannot be called by class name directly.
// Child.normalFunc()                // Cannot be called by class name directly.

/*
 Notes:
 ___________________________________________________________________________
 |Types------Redeclare------Override------Call by object------Call by Class|
 |Final----------0--------------0---------------1------------------0-------|
 |Static---------1--------------0---------------0------------------1-------|
 |Class----------1--------------1---------------0------------------1-------|
 |Normal---------0--------------1---------------1------------------0-------|
 ---------------------------------------------------------------------------

 Final vs Normal function: Both are same but normal methods can be overridden.
 Static vs Class function: Both are same but class methods can be overridden.
 */

আউটপুট: ফাংশন সমস্ত ধরণের আউটপুট


-6

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


1
শ্রেণি সোমক্লাস {শ্রেণি ফানক কিছু টাইপমেথোদ () type // ধরণের পদ্ধতি প্রয়োগ এখানে চলে}} সোমারক্লাস.সোমটাইপমাইথড ()
কুমার উত্সব

এটি প্রশ্নের কোনও উত্তর দেয় না। তিনি এর মধ্যে পার্থক্য জিজ্ঞাসা staticএবং classকীওয়ার্ড।
ডগ ম্যাকব্রাইড
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.