একই শ্রেণি থেকে নির্মিত অবজেক্টের কী অনন্য পদ্ধতির সংজ্ঞা থাকতে পারে?


14

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

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

যদি আমি ভুল না হয়ে থাকি তবে আপনি এই জাভাস্ক্রিপ্টটি করতে পারেন? এই প্রশ্নের পাশাপাশি আমি জিজ্ঞাসা করছি, কেউ কেন এটি করতে চাইবে?


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

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

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

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

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

উত্তর:


9

বেশিরভাগ (শ্রেণিবদ্ধ) ওওপি ভাষায় পদ্ধতিগুলি টাইপ অনুসারে স্থির হয়।

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

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

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

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


আপনার প্রথম বাক্যটি বোঝায় না। শ্রেণিভিত্তিক ওওপি স্থির প্রকারের সাথে কী করতে পারে?
বার্গি

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

@ বার্গি: ক্লাস ভিত্তিক ওওপিতে "ক্লাস" এবং "টাইপ" শব্দটি মূলত একই জিনিসটিকে বোঝায়। যেহেতু টাইপ পূর্ণসংখ্যার মান "হ্যালো" রাখার জন্য এটি কোনও অর্থবোধ করে না তাই ধরণের কর্মচারীর মান বা পদ্ধতি যা শ্রেণীর কর্মচারীর অন্তর্গত নয় সেগুলি পাওয়াও বোধগম্য নয়।
slebetman

@ স্লেবেটম্যান: আমি বোঝাতে চাইছি যে একটি শ্রেণিভিত্তিক ওওপি ভাষার অগত্যা শক্তিশালী, স্ট্যাটিকালি প্রয়োগ করা টাইপিং নেই।
বার্গি

@ বার্গি: উপরের উত্তরের "সর্বাধিক" এর অর্থ (বেশিরভাগ অর্থ সমস্ত নয়)। আমি কেবল আপনার "এটিতে কী করতে হবে" মন্তব্যটি করছি।
slebetman

6

আপনার প্রশ্নের অনুপ্রেরণা অনুমান করা শক্ত, এবং তাই কিছু সম্ভাব্য উত্তর আপনার আসল আগ্রহের দিকে লক্ষ্য রাখতে পারে বা নাও পারে।

এমনকি কিছু অ-প্রোটোটাইপ ভাষায়ও এই প্রভাবটি প্রায় অনুমান করা সম্ভব।

জাভাতে, উদাহরণস্বরূপ, একটি বেনামে অভ্যন্তরীণ শ্রেণি আপনি বর্ণনা করছেন তার থেকে খুব কাছাকাছি - আপনি যে পদ্ধতি বা পদ্ধতিগুলি চান তার উপর ভিত্তি করে আপনি মূলটির একটি উপক্লাস তৈরি এবং ইনস্ট্যান্ট করতে পারেন। ফলস্বরূপ শ্রেণিটি instanceofমূল শ্রেণি হবে তবে একই শ্রেণি হবে না ।

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

এটি বলেছিল, এমনকি প্রাক-জে 8, এটি প্রায়শই পার্থক্যটিকে একটি ক্ষেত্র বা তিনটিতে স্থানান্তর করতে এবং কনস্ট্রাক্টারে ইনজেকশনের জন্য পুনরুদ্ধার করা যেতে পারে। অবশ্যই জে 8 এর সাথে, পদ্ধতিটি নিজেই ক্লাসে ইনজেকশনের ব্যবস্থা করা যেতে পারে, যদিও অন্য কোনও রিফ্যাক্টরিং ক্লিনার হতে পারে এমনটা করার একটা প্রলোভন থাকতে পারে (যতটা শীতল না হলে)।


6

আপনি এমন কোনও ভাষা চেয়েছিলেন যা প্রতি-দৃষ্টান্তের পদ্ধতিগুলি সরবরাহ করে। জাভাস্ক্রিপ্টের জন্য ইতিমধ্যে একটি উত্তর রয়েছে, সুতরাং আসুন দেখুন কীভাবে এটি কমন লিস্পে করা হয়, যেখানে আপনি EQL-বিশেষজ্ঞ ব্যবহার করতে পারেন:

;; define a class
(defclass some-class () ())

;; declare a generic method
(defgeneric some-method (x))

;; specialize the method for SOME-CLASS
(defmethod some-method ((x some-class)) 'default-result)

;; create an instance named *MY-OBJECT* of SOME-CLASS
(defparameter *my-object* (make-instance 'some-class))

;; specialize SOME-METHOD for that specific instance
(defmethod some-method ((x (eql *my-object*))) 'specific-result)

;; Call the method on that instance
(some-method *my-object*)
=> SPECIFIC-RESULT

;; Call the method on a new instance
(some-method (make-instance 'some-class))
=> DEFAULT-RESULT

কেন?

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

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


5

আপনি সিঙ্গেলটন বস্তু ব্যবহার করে রুবিতে এটি করতে পারেন:

class A
  def do_something
    puts "Hello!"
  end
end

obj = A.new
obj.do_something

def obj.do_something
  puts "Hello world!"
end

obj.do_something

উত্পাদন:

Hello!
Hello world!

ব্যবহার হিসাবে, এটি আসলে রুবি ক্লাস এবং মডিউল পদ্ধতিগুলি করে। উদাহরণ স্বরূপ:

def SomeClass
  def self.hello
    puts "Hello!"
  end
end

আসলে বস্তুটিতে একটি সিঙ্গলটন পদ্ধতি সংজ্ঞায়িত helloকরছে ।ClassSomeClass


আপনি কি উত্তরটি মডিউল এবং প্রসারিত-পদ্ধতি দিয়ে প্রসারিত করতে চান? (নতুন পদ্ধতির সাহায্যে অবজেক্টগুলি প্রসারিত করার জন্য কিছু অন্যান্য উপায় দেখানোর জন্য)?
নট

@ কুনট: আমি নিশ্চিত যে extendবাস্তবে কেবলমাত্র সিঙ্গলটন ক্লাস তৈরি করে এবং পরে মডিউলটি সিঙ্গলটন শ্রেণিতে আমদানি করে।
লিনাকিনিওস

5

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

আপনি ব্লাব প্যারাডক্স থেকে কিছুটা ভুগছেন , মূলত যে কোনও ভাষা বৈশিষ্ট্যের মূল্য আপনি যদি আসল প্রোগ্রামে ব্যবহার না করেন ততক্ষণ পর্যন্ত এটি দেখা মুশকিল। সুতরাং এমন সুযোগের সন্ধান করুন যেখানে আপনি মনে করেন এটি কার্যকর হতে পারে, চেষ্টা করে দেখুন এবং কী ঘটে।

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


1

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


0

আপনি সি # এবং অন্যান্য অন্যান্য অনুরূপ ভাষায় এর মতো কিছু করতে পারেন।

public class MyClass{
    public Func<A,B> MyABFunc {get;set;}
    public Action<B> MyBAction {get;set;}
    public MyClass(){
        //todo assign MyAFunc and MyBAction
    }
}

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

0

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

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

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


0

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

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

এটি মঙ্কি-প্যাচিংয়ের মতো কিছু কৃপণ ক্রিয়াকে সহজ করে তোলে যেখানে আপনি ক্লাসের উদাহরণটি ঝাপটান করতে পারেন যাতে আপনি একটি বন্ধ লাইব্রেরির সাথে কথোপকথন করতে পারেন যাতে তারা অগ্রাহ্য করেনি।


0

আমি বলছি না যে এটি করা ভাল, তবে পাইথনের ক্ষেত্রে এটি তুচ্ছভাবে সম্ভব। আমি আমার মাথার উপরের দিক থেকে ভাল ব্যবহারের বিষয়টি বলতে পারি না তবে আমি নিশ্চিত যে এগুলি বিদ্যমান।

    class Foo(object):
        def __init__(self, thing):
            if thing == "Foo":
                def print_something():
                    print "Foo"
            else:
                def print_something():
                    print "Bar"
            self.print_something = print_something

    Foo(thing="Foo").print_something()
    Foo(thing="Bar").print_something()
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.