পদ্ধতি ওভারলোডিং কখন উপযুক্ত?


10

মনে করুন আমি একটি বিদ্যমান, যুক্তিসঙ্গত বৃহত সিস্টেমে কাজ করছি। আমার myObjectক্লাসের একটি বিষয় রয়েছে MyClass(উদাহরণস্বরূপ, ধরুন আমি জাভাতে কাজ করছি)। myObjectএকটি Collection, বলুন, একটি Listএবং অন্যান্য অবজেক্টগুলি সমন্বিত এমন একটি রচনা যা (আমার মনে হয়) অপ্রাসঙ্গিক। এটিতে ডেলিগেট পদ্ধতি রয়েছে যা কেবল এটি তৈরি করা হয়েছে এমন পদ্ধতিগুলির প্রতি আহ্বান জানাতে পরিবেশন করে Listযাতে Listএটি প্রকাশিত হয় নি তা নিশ্চিত করার জন্য (দুঃখিত যদি আমি আমার পরিভাষাটি ভুল করে ফেলেছি)।

ধরা যাক Listএটি একটি List<String>তবে কোনও কারণে, প্রধান অ্যাক্সেস পদ্ধতিটি শ্রেণীর জন্য একটি মুখোশ পদ্ধতি SomeOtherClass। আমি যদি আমার মধ্যে একটি নতুন মান জুড়ি wantedোকাতে চাইতাম Listতবে আমার কাছে একটি অবজেক্ট SomeOtherClassবলে মনে হবে someObject। আমি কল করব myObject.insert(someObject)এবং insertপদ্ধতির অভ্যন্তরে এমন কিছু জাদু থাকবে যা এটিতে একটি পুনরুদ্ধার Stringকরবে List<String>

মনে করুন এখনই আমি কেবল একটি Stringমান পেয়েছি এবং SomeOtherClassobjectোকানোর জন্য কোনও বস্তু নেই । ধরে নিচ্ছি আমি insertপদ্ধতিটি সংশোধন করতে পারছি না কারণ এটি এই সিস্টেমে সমস্ত কিছু ভেঙে ফেলবে। তাহলে আমি কি insertপদ্ধতিটি ওভারলোড করব ? নাকি আমি একটি নতুন বস্তু তৈরি করা উচিত SomeOtherClassপ্রত্যেক সময় আমি কল করতে চান insert?

আমার ধারণা আমি যদি এটি ওভারলোড না করে থাকি তবে এটি এমন কিছু দেখাচ্ছে ...

public void insert(String s) {
    ...
}

public void insert(SomeOtherObject obj) {
    this.insert(obj.magicStringMethod());
}

(এই উদাহরণটি গতকাল ওভারলোডিং সম্পর্কে যে একইরকম (কিছুটা জটিল) পরিস্থিতি তৈরি হয়েছিল তার ভিত্তিতে একটি স্বতন্ত্র ধাঁধা।

কোনও পদ্ধতির ওভারলোডের জন্য এটি কি উপযুক্ত জায়গা হবে? যদি তা না হয় তবে আমি কখন কোনও পদ্ধতি ওভারলোড করব?


জাভা ধরে নিচ্ছেন, আপনি কি এই সমস্যা সমাধানের জন্য জেনারিক্স ব্যবহার করে দেখেছেন? আমার ধারণা আমি সত্যই যা জিজ্ঞাসা করছি তা হল স্ট্রিং আসলে কী প্রতিনিধিত্ব করে? যদি এটি সত্যই সত্যিকারের ডোমেন অবজেক্টের উপস্থাপনা থাকে তবে এই সমস্যাটি সমাধানের আর একটি সম্ভাব্য উপায় আছে
মার্তিজান ভারবার্গ

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

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

উত্তর:


7

আপনি বিভিন্ন ধরণের সমর্থন করতে ইচ্ছুক হলে আপনি ওভারলোড:

public overload void MyMethod(int value)
{ 
}

public overload void MyMethod(bool value)
{
}

public overload void MyMethod(string value)
{
}

বা বিভিন্ন প্যারামিটার তালিকা ব্যবহার করে একটি প্রগতিশীল ইন্টারফেস সমর্থন করতে:

public overload void MyOtherMethod()
{
    this.MyOtherMethod(DefaultValue);
}

public overload void MyOtherMethod(int value)
{
    this.MyOtherMethod(value, DefaultOtherValue);
}

public overload void MyOtherMethod(int value, bool otherValue)
{
    ...
}

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


7

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

এগুলি যথাযথভাবে ওভারলোড করা হয়:

public int sum(int a, int b){
    return a+b;
}

public double sum(double a, double b){
    return a+b;
}

এগুলি নয়:

public int sum(int a, int b){
    return a+b;
}

public double sum(double a, double b){
    return a-b;
}

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

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


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

5

মূলত পদ্ধতির পরামিতিগুলি কীভাবে পদ্ধতিটি আচরণ করবে তা নির্দেশ করে।

একটি দ্রুত উদাহরণ হবে:

class Calc{
    //...
    public int sum(int a, int b){
        return a+b;
    }
    public double sum(double a, double b){
        return a+b;
    }
    //...
}

আপনি যদি পদ্ধতিটির যোগফলটি (ক, খ) পাস করেন তবে এটি জানেন যে এটির প্রথম প্রয়োগটি কল করা উচিত, যেহেতু পদ্ধতি কলটি পদ্ধতিটির স্বাক্ষরের সাথে মিলে যায় (যেমন ডাবল যোগফল (ডাবল, ডাবল) আপনি দিলে কাজ করবে না যোগফল দুটি পূর্ণসংখ্যা)।

কলটির স্বাক্ষর অবশ্যই উপলব্ধ বাস্তবায়নের সাথে মিলে যায়, সুতরাং আপনার কাছে এটি না থাকলে যোগফল (স্ট্রিং, স্ট্রিং) চেষ্টা করার চেষ্টা করবে না:

class Calc{
    //...
    public int sum(int a, int b){
        return a+b;
    }
    public double sum(double a, double b){
        return a+b;
    }
    public string sum(String a, String b){
        return "" + (Double.parseDouble(a) + Double.parseDouble(b));
    }
    //...
}

tl; dr: আপনি একই নাম দিয়ে কোনও পদ্ধতি যেই প্যারামিটার দিয়ে দেন সে অনুযায়ী ক্লাসটি সঠিক পদ্ধতি পরিচালনা করতে পারে।

উত্তরাধিকার সূত্রে এটিকে ওভাররাইডিং বলা হয়

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

কল্পনা করুন যে আপনার আছে class Robotএবং একটি পদ্ধতি বলা হয়েছে fireAtTarget(Target target)... যা fireWeaponA(target); fireWeaponB(target); fireWeaponC(target);একে একে একে একে কল করে । আপনি রোবোট_আরমি নামে একটি সংগ্রহ করতে চান যাতে আপনি কেবল রোবট শ্রেণীর অবজেক্ট যুক্ত করতে পারেন। রোবট তার fireWeaponX()পদ্ধতিতে ডিফল্টরূপে মেশিনগান গুলি চালায়।

তারপরে আপনি কীভাবে রোবটকে আবার পুরোপুরি প্রয়োগ করতে চান class LazorRobotএবং class MissileRobotনা ?, না, কেবল ল্যাজাররবোট এবং মিসাইলরোবটকে রোবটের উত্তরাধিকারী করুন এবং ল্যাজার্জ বা ক্ষেপণাস্ত্রগুলি ব্যবহার করার জন্য প্রতিটি পদ্ধতিকে ওভারলোড করুন এবং fireWeaponX()পুনর্বিবেচনা না করেই আপনি বিভিন্ন অস্ত্রের সাথে একই আচরণ করবেন will পদ্ধতি বাকি।

tl; dr: পদ্ধতির আচরণটি ইন্টারফেসটি না ভেঙে ক্লাসের উপর নির্ভর করে (রোবোট_আর্মি কেবল রোবটকেই গ্রহণ করে, তবে রোবটের উত্তরাধিকার সূত্রে যে কোনও শ্রেণি এক্সটেনশনে গ্রহণ করে)।


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

ডার্প, ক্যাফিন আমাকে এবার পেয়েছে = পি, দ্বিতীয় স্বর প্রথম অংশ হিসাবে রেখেছিল এবং প্রথম হিসাবে প্রথম আগ্রহের জন্য দ্বিতীয় হিসাবে রেখেছিল। সংশোধনীর জন্য ধন্যবাদ.
ডিউকোফেমিং

যদি আমি আপনার উত্তরটি সঠিকভাবে বুঝতে পারি তবে আমার কেবলমাত্র পরামিতিগুলি দেখার সময় ওভারলোডিং হওয়া উচিত, আমাকে বলুন, sum(String, String)এবং এর মধ্যে আচরণের পার্থক্যগুলি অনুমান করার অনুমতি দেবে sum(int, int)?
blahman

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

1
@ ব্লাহম্যান বিটিডাব্লু এবং অন্য কোনও বিষয়ে, যখন আপনার অনেকগুলি পরামিতি রয়েছে এবং সেগুলির কয়েকটি optionচ্ছিক হয় কখনও কখনও কেবলমাত্র একটি একক অবজেক্ট বা ডেটা কাঠামো প্রেরণ করা ভাল যে সমস্ত ডিফল্ট মান রয়েছে, সুতরাং আপনি এই জাতীয় অবজেক্ট বা ডেটার বৈশিষ্ট্যগুলি পরিবর্তন করেন কাঠামো। এইভাবে প্রতিবার একটি একক প্যারামিটার যুক্ত করার জন্য আপনাকে একই পদ্ধতির 20 টি সংস্করণ তৈরি করতে হবে না।
ডিউকোফেমিং
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.