সি # তে একাধিক উত্তরাধিকার


212

যেহেতু একাধিক উত্তরাধিকার খারাপ (এটি উত্সটিকে আরও জটিল করে তোলে) সি # সরাসরি এ জাতীয় নিদর্শন সরবরাহ করে না। তবে কখনও কখনও এই ক্ষমতা অর্জনে সহায়ক হবে।

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

public interface IFirst { void FirstMethod(); }
public interface ISecond { void SecondMethod(); }

public class First:IFirst 
{ 
    public void FirstMethod() { Console.WriteLine("First"); } 
}

public class Second:ISecond 
{ 
    public void SecondMethod() { Console.WriteLine("Second"); } 
}

public class FirstAndSecond: IFirst, ISecond
{
    First first = new First();
    Second second = new Second();
    public void FirstMethod() { first.FirstMethod(); }
    public void SecondMethod() { second.SecondMethod(); }
}

প্রতিবার আমি ইন্টারফেসগুলির মধ্যে একটিতে কোনও পদ্ধতি যুক্ত করার সাথে সাথে আমার ফার্স্টএন্ডসেকেন্ড ক্লাসটিও পরিবর্তন করা দরকার ।

একাধিক বিদ্যমান ক্লাসগুলিকে নতুন করে ক্লাসে ইনজেক্ট করার মতো উপায় কি এটি সি ++ এ সম্ভব?

কোনও ধরণের কোড জেনারেশন ব্যবহার করে কোনও সমাধান হতে পারে?

বা এটি দেখতে (কল্পিত সি # সিনট্যাক্স) এর মতো দেখাতে পারে:

public class FirstAndSecond: IFirst from First, ISecond from Second
{ }

যাতে ইন্টারফেসগুলির মধ্যে কোনওটি সংশোধন করার সময় ফার্স্টএন্ডসেকেন্ড ক্লাসটি আপডেট করার দরকার নেই।


সম্পাদনা

ব্যবহারিক উদাহরণ বিবেচনা করা আরও ভাল হবে:

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

আমি যতদূর জানি আপনার বর্তমানে এটি করার দুটি উপায় রয়েছে:

  1. উপাদান থেকে উত্তরাধিকার সূত্রে প্রাপ্ত নতুন ক্লাসটি লিখুন এবং টেক্সটসিপিপ্লিয়েন্ট শ্রেণীর ইন্টারফেস প্রয়োগ করে ক্লাসের নিজের উদাহরণটি ফার্স্টএন্ডসেকেন্ডের মতো দেখানো হয়েছে using

  2. একটি নতুন শ্রেণি লিখুন যা টেক্সটটিসিপিপ্লায়েন্টের উত্তরাধিকার সূত্রে প্রাপ্ত এবং কোনওভাবে আইসিম্পোম্পোন্ট প্রয়োগ করে (বাস্তবে এটি এখনও চেষ্টা করে নি)।

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

কোন্দল এড়াতে কোড কোড তৈরির মাধ্যমে এটি করা যেতে পারে যেখানে ফলাফলটি পরে পরিবর্তন করা যেতে পারে তবে হাত দিয়ে এটাই টাইপ করা পাছায় খাঁটি ব্যথা।


এই ছদ্মবেশে কেবল যে একাধিক উত্তরাধিকার নয়, এটি কীভাবে কম জটিল?
হার্পো

3.5 এ নতুন এক্সটেনশন পদ্ধতিগুলি এবং এটি কীভাবে কাজ করে (স্ট্যাটিক সদস্য কল উত্পন্নকরণ) সম্পর্কে চিন্তাভাবনা করা, এটি পরবর্তী। নেট ভাষার বিবর্তনগুলির মধ্যে একটি হতে পারে।
ল্যারি

কখনও কখনও আমি ভাবছি কেন লোকেরা কেবল ... ক্লাস এ: ক্লাস বি: ক্লাস সি করে না?
চিবুয়েজ ওপাটা

@ নাজারমারজা: লিঙ্কটি পরিবর্তন হয়েছে। এখন: একাধিক উত্তরাধিকার নিয়ে সমস্যা
ক্রেগ ম্যাককুইন

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

উত্তর:


125

যেহেতু একাধিক উত্তরাধিকার খারাপ (এটি উত্সটিকে আরও জটিল করে তোলে) সি # সরাসরি এ জাতীয় নিদর্শন সরবরাহ করে না। তবে কখনও কখনও এই ক্ষমতা অর্জনে সহায়ক হবে।

সি # এবং। নেট সিএলআর এমআই বাস্তবায়ন করেনি কারণ তারা সি #, ভিবি নেট এবং অন্যান্য ভাষার মধ্যে কীভাবে আন্তঃচালনা করবে তা এই সিদ্ধান্তে পৌঁছেছে না, "কারণ এটি উত্সকে আরও জটিল করে তুলবে"

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

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

ততক্ষণ আপনি তার পরিবর্তে প্রক্সি অবজেক্ট এবং একাধিক ইন্টারফেসের সাথে আটকে আছেন :(


39
সিএলআর একাধিক বাস্তবায়ন উত্তরাধিকার সমর্থন করে না, কেবল একাধিক ইন্টারফেস উত্তরাধিকার (যা সি # তেও সমর্থিত)।
জর্দো

4
@ জর্দো: সম্পূর্ণতার জন্য: সংকলকরা সিএলআর-তে তাদের ধরণের জন্য এমআই তৈরি করা সম্ভব। এটিতে এর সতর্কতা রয়েছে, উদাহরণস্বরূপ এটি সিএলএসের অনুগত নয়। আরও তথ্যের জন্য দেখুন এই (2004) নিবন্ধটি ব্লগস.এমএসএনএন
বি /

2
@ মিঃহ্যাপি: অত্যন্ত আকর্ষণীয় নিবন্ধ। আমি আসলে সি # এর জন্য ট্রাইট কমপোজিশনের কিছু উপায় অনুসন্ধান করেছি , একবার দেখুন।
জর্দো

10
@ মনদীপজানজুয়া আমি এ জাতীয় কোনও দাবি করি নি, আমি বলেছিলাম 'এটি ভালভাবে পরিচয় করিয়ে দিতে পারে' এই বিষয়টি এখনও অব্যাহত রয়েছে যে ইসিএমএ স্ট্যান্ডার্ড সিএলআর একাধিক উত্তরাধিকারের জন্য আইএল যন্ত্রপাতি সরবরাহ করে, কেবল কিছুই এটিকে পুরোপুরি ব্যবহার করে না।
ইয়াননার্টন

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

214

একাধিক উত্তরাধিকার অনুকরণ করার চেষ্টা না করে কেবল রচনা ব্যবহার বিবেচনা করুন । আপনি নির্ধারণ করতে কি ক্লাস রচনা, যেমন আপ করতে ইন্টারফেস ব্যবহার করতে পারেন: ISteerableটাইপ একটি সম্পত্তি বোঝা SteeringWheel, IBrakableটাইপ একটি সম্পত্তি বোঝা BrakePedalইত্যাদি

এটি সম্পন্ন হয়ে গেলে, আপনি সেই সংযুক্ত বৈশিষ্ট্যগুলিতে কল করার পদ্ধতিগুলিকে আরও সহজ করতে সি # 3.0 এ যুক্ত এক্সটেনশন পদ্ধতি বৈশিষ্ট্যটি ব্যবহার করতে পারেন , যেমন:

public interface ISteerable { SteeringWheel wheel { get; set; } }

public interface IBrakable { BrakePedal brake { get; set; } }

public class Vehicle : ISteerable, IBrakable
{
    public SteeringWheel wheel { get; set; }

    public BrakePedal brake { get; set; }

    public Vehicle() { wheel = new SteeringWheel(); brake = new BrakePedal(); }
}

public static class SteeringExtensions
{
    public static void SteerLeft(this ISteerable vehicle)
    {
        vehicle.wheel.SteerLeft();
    }
}

public static class BrakeExtensions
{
    public static void Stop(this IBrakable vehicle)
    {
        vehicle.brake.ApplyUntilStop();
    }
}


public class Main
{
    Vehicle myCar = new Vehicle();

    public void main()
    {
        myCar.SteerLeft();
        myCar.Stop();
    }
}

13
যদিও এটি মূল বিষয় - এর মত একটি ধারণা রচনাটি সহজ করবে।
জন স্কিটি

9
হ্যাঁ, তবে এমন ব্যবহারের ক্ষেত্রে রয়েছে যেখানে মূল বিষয়টির অংশ হিসাবে আপনার সত্যিকারের পদ্ধতিগুলির প্রয়োজন
ডেভিড পিয়ের

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

4
দুর্দান্ত উত্তর! সংক্ষিপ্ত, বোঝা সহজ, খুব দরকারী চিত্রণ। ধন্যবাদ!
এজে।

3
আমরা যদি চেক করতে চান পারে myCarসমাপ্ত স্টিয়ারিং কলিং আগে বাম হয়েছে Stop। অতিরিক্ত গতিতে Stopথাকাকালীন myCarএটি প্রয়োগ করা যেতে পারে । : ডি
দেবরাজ গাদাবী

16

আমি একটি সি # পোস্ট-সংকলক তৈরি করেছি যা এই ধরণের জিনিস সক্ষম করে:

using NRoles;

public interface IFirst { void FirstMethod(); }
public interface ISecond { void SecondMethod(); }

public class RFirst : IFirst, Role {
  public void FirstMethod() { Console.WriteLine("First"); }
}

public class RSecond : ISecond, Role {
  public void SecondMethod() { Console.WriteLine("Second"); }
}

public class FirstAndSecond : Does<RFirst>, Does<RSecond> { }

আপনি ভিজ্যুয়াল স্টুডিও পোস্ট-বিল্ড-ইভেন্ট হিসাবে পোস্ট-সংকলকটি চালাতে পারেন:

সি: \ কিছু_পথ \ ন্রোলস-ভি0.1.0-বিন \ নাটেট.এক্সই "Tar (টার্গেটপথ)"

একই সমাবেশে আপনি এটি ব্যবহার করুন:

var fas = new FirstAndSecond();
fas.As<RFirst>().FirstMethod();
fas.As<RSecond>().SecondMethod();

অন্য সমাবেশে আপনি এটি ব্যবহার করুন:

var fas = new FirstAndSecond();
fas.FirstMethod();
fas.SecondMethod();

6

আপনার একটি বিমূর্ত বেস ক্লাস থাকতে পারে যা আইফারস্ট এবং আইসকন্ড উভয়ই প্রয়োগ করে এবং তারপরে ঠিক সেই বেস থেকে উত্তরাধিকারী।


এটি সম্ভবত সেরা সমাধান, তবে অগত্যা সেরা ধারণা নয়: পি
লেপ্পি '

1
আপনি যখন ইন্টারফেসগুলিতে পদ্ধতিগুলি যুক্ত করেন তখন কি আপনাকে বিমূর্ত শ্রেণি সম্পাদনা করতে হবে না?
রিক 13

রিক: আপনি কতটা অলস, যখন আপনাকে কেবল একবার এটি করতে হবে?
leppie

3
@ লেপ্পি - "প্রতিবার আমি ইন্টারফেসগুলির মধ্যে একটিতে কোনও পদ্ধতি যুক্ত করার সাথে সাথে ফার্স্টএন্ডসেকেন্ড শ্রেণিটিও পরিবর্তন করা দরকার" " মূল প্রশ্নের এই অংশটি সমাধান দ্বারা সমাধান করা হয় না, তাই না?
রিক

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

3

এমআই খারাপ নয়, প্রত্যেকে (গুরুত্ব সহকারে) এটি ব্যবহার করেছে তারা এটিকে পছন্দ করে এবং কোডটি জটিল করে না! কমপক্ষে অন্য কনস্ট্রাক্টগুলির চেয়ে কোড জটিল করে তুলতে পারে না। ছবিতে এমআই থাকুক বা না থাকুক খারাপ কোড হ'ল খারাপ কোড।

যাইহোক, আমি একাধিক উত্তরাধিকার ভাগ করে নিতে চেয়েছিলাম তার একটি দুর্দান্ত সামান্য সমাধান পেয়েছি, এটি এখানে; http://ra-ajax.org/lsp-liskov-subst येशू- প্রিন্সিলে- to-be-or-not-to-be.blog বা আপনি আমার সিগ লিঙ্কটি অনুসরণ করতে পারেন ... :)


একাধিক উত্তরাধিকার পাওয়া এবং উপাসনা ও বর্ধনের সময় পরিচয় সংরক্ষণ করা কি সম্ভব? সমাধান আমি একাধিক উত্তরাধিকার সূত্রে সমস্যার জন্য জানি কাস্ট যে পরিচয়-সংরক্ষণের করছে থাকার কাছাকাছি ঘুরা (যদি myFooধরনের হয় Fooথেকে, যা উত্তরাধিকারী Mooএবং Gooউভয় যা উত্তরাধিকারী এর থেকে Boo, তারপর (Boo)(Moo)myFooএবং (Boo)(Goo)myFooসমতুল্য হবে না)। আপনি কোনও পরিচয়-সংরক্ষণের পদ্ধতির বিষয়ে সচেতন?
সুপারক্যাট

1
আপনি লিঙ্কটি অনুসরণ করতে ওয়েব.আরচিভ.অর্গ বা অনুরূপ ব্যবহার করতে পারেন, তবে এটি এখানে মূল প্রশ্নের প্রস্তাবিত সমাধানটির আরও বিস্তারিত আলোচনা হতে পারে।
মাইকবিটেন

2

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

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

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

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


2

সি # 8 দিয়ে এখন আপনার ইন্টারফেস সদস্যদের ডিফল্ট প্রয়োগের মাধ্যমে কার্যত একাধিক উত্তরাধিকার রয়েছে:

interface ILogger
{
    void Log(LogLevel level, string message);
    void Log(Exception ex) => Log(LogLevel.Error, ex.ToString()); // New overload
}

class ConsoleLogger : ILogger
{
    public void Log(LogLevel level, string message) { ... }
    // Log(Exception) gets default implementation
}

4
হ্যাঁ, তবে লক্ষ্য করুন যে উপরের অংশে আপনি এটি করতে সক্ষম হবেন না new ConsoleLogger().Log(someEception)- এটি কেবল কার্যকর হবে না, আপনাকে ILoggerডিফল্ট ইন্টারফেস পদ্ধতিটি ব্যবহার করার জন্য আপনার অবজেক্টকে স্পষ্টভাবে কাস্ট করতে হবে। সুতরাং এর উপযোগিতা কিছুটা সীমাবদ্ধ।
দিমিত্রি নেস্টারুক

1

যদি আপনি এই সীমাবদ্ধতার সাথে বেঁচে থাকতে পারেন যে আইএফস্ট এবং আইসকন্ডের পদ্ধতিগুলি কেবল আইফার্স্ট এবং আইসকন্ডের (যেমন আপনার উদাহরণ হিসাবে) চুক্তির সাথে ইন্টারঅ্যাক্ট করতে পারে ... আপনি এক্সটেনশন পদ্ধতিগুলির সাথে যা চান তা করতে পারেন। বাস্তবে, এটি খুব কমই ঘটে।

public interface IFirst {}
public interface ISecond {}

public class FirstAndSecond : IFirst, ISecond
{
}

public static MultipleInheritenceExtensions
{
  public static void First(this IFirst theFirst)
  {
    Console.WriteLine("First");
  }

  public static void Second(this ISecond theSecond)
  {
    Console.WriteLine("Second");
  }
}

///

public void Test()
{
  FirstAndSecond fas = new FirstAndSecond();
  fas.First();
  fas.Second();
}

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


1

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

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

উদাহরণ স্বরূপ:

 namespace OOP
 {
     class Program
     {
         static void Main(string[] args)
         {
             Child somechild = new Child();
             somechild.DoHomeWork();
             somechild.CheckingAround();
             Console.ReadLine();
         }
     }

     public class Father 
     {
         public Father() { }
         public void Work()
         {
             Console.WriteLine("working...");
         }
         public void Moonlight()
         {
             Console.WriteLine("moonlighting...");
         }
     }


     public class Mother 
     {
         public Mother() { }
         public void Cook()
         {
             Console.WriteLine("cooking...");
         }
         public void Clean()
         {
             Console.WriteLine("cleaning...");
         }
     }


     public class Child 
     {
         public Father MyFather { get; set; }
         public Mother MyMother { get; set; }

         public Child()
         {
             MyFather = new Father();
             MyMother = new Mother();
         }

         public void GoToSchool()
         {
             Console.WriteLine("go to school...");
         }
         public void DoHomeWork()
         {
             Console.WriteLine("doing homework...");
         }
         public void CheckingAround()
         {
             MyFather.Work();
             MyMother.Cook();
         }
     }


 }

এই কাঠামোর ক্লাসের সাথে সন্তানের পিতা বা মাতার সমস্ত পদ্ধতি এবং বৈশিষ্ট্য অ্যাক্সেস থাকবে, একাধিক উত্তরাধিকারের অনুকরণ করে পিতামাতার ক্লাসগুলির উদাহরণ হ'ল। বেশ একরকম নয় তবে এটি ব্যবহারিক।


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

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

EXTRACT ইন্টারফেস: শ্রেণি স্বাক্ষর উপর ডান ক্লিক করুন, তারপর ইন্টারফেস নিষ্কাশন ... VS2015 একই প্রক্রিয়ায় ছাড়া আপনি সঠিক ক্লিক করতে হবে, তারপর নির্বাচন Quick Actions and Refactorings...এই একটি জানতে হবে, এটা আপনি অনেক সময় সংরক্ষণ করতে হবে
Chef_Code

1

আমরা সকলেই এটির সাথে ইন্টারফেসের পথটি নীচে নিয়ে যাচ্ছি বলে মনে হচ্ছে, তবে স্পষ্টতই অন্য সম্ভাবনাটি এখানে, ওওপি যা করার কথা বলেছিল তা করা, এবং আপনার উত্তরাধিকার গাছটি তৈরি করা ... (ক্লাস ডিজাইনটি এটি কি এটি নয় সম্পর্কিত?)

class Program
{
    static void Main(string[] args)
    {
        human me = new human();
        me.legs = 2;
        me.lfType = "Human";
        me.name = "Paul";
        Console.WriteLine(me.name);
    }
}

public abstract class lifeform
{
    public string lfType { get; set; }
}

public abstract class mammal : lifeform 
{
    public int legs { get; set; }
}

public class human : mammal
{
    public string name { get; set; }
}

এই কাঠামোটি কোডের পুনরায় ব্যবহারযোগ্য ব্লক সরবরাহ করে এবং অবশ্যই ওওপি কোডটি কীভাবে লেখা উচিত?

যদি এই নির্দিষ্ট পদ্ধতির বিলটি পুরোপুরি ফিট না করে তবে আমরা প্রয়োজনীয় সামগ্রীর উপর ভিত্তি করে কেবল নতুন ক্লাস তৈরি করি ...

class Program
{
    static void Main(string[] args)
    {
        fish shark = new fish();
        shark.size = "large";
        shark.lfType = "Fish";
        shark.name = "Jaws";
        Console.WriteLine(shark.name);
        human me = new human();
        me.legs = 2;
        me.lfType = "Human";
        me.name = "Paul";
        Console.WriteLine(me.name);
    }
}

public abstract class lifeform
{
    public string lfType { get; set; }
}

public abstract class mammal : lifeform 
{
    public int legs { get; set; }
}

public class human : mammal
{
    public string name { get; set; }
}

public class aquatic : lifeform
{
    public string size { get; set; }
}

public class fish : aquatic
{
    public string name { get; set; }
}

0

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


8
দয়া করে এমআই কে সি ++ দ্বারা বিচার করবেন না, এটি পিএইচপি দ্বারা ওওপি বা পিন্টোস দ্বারা অটোমোবাইলগুলি বিচার করার মতো। এই সমস্যাটি সহজেই সমাধানযোগ্য: সেখানে কোনও অস্পষ্টতা নেই এবং কোনও চমকও নেই।
Jörg ডব্লু মিটাগ

2
@ এমপি: না, আইফেল সত্যিকারের একাধিক বাস্তবায়নের উত্তরাধিকার সরবরাহ করে। পুনর্নামকরণের অর্থ উত্তরাধিকার শৃঙ্খলাটি হারাতে হবে না, এটি ক্লাসের castালাইযোগ্যতা হ্রাস করবে না।
হাবেল

0

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

  1. এক্স এক্স এর জন্য ডিফল্ট কার্যকারিতা সরবরাহ করবে, তাই এক্স এর কোডটিতে কেবল স্টাফ অন্তর্ভুক্ত করতে হবে যা ওয়াই থেকে আলাদা which
  2. প্রায় যে কোনও জায়গায় ওয়াইয়ের প্রত্যাশা করা হত, পরিবর্তে একটি এক্স ব্যবহার করা যেতে পারে।

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


0

আমি জানি আমি জানি যদিও এর অনুমতি নেই এবং আরও অনেক কিছু আছে, কিছু সময়ের জন্য আপনার সত্যিকারের এটি প্রয়োজন তাদের জন্য:

class a {}
class b : a {}
class c : b {}

যেমন আমার ক্ষেত্রে আমি এই ক্লাসটি করতে চেয়েছিলাম বি: ফর্ম (উইন্ডোজ.ফর্মগুলি হ্যাঁ) শ্রেণি সি: বি}}

কারণ অর্ধেক ফাংশনটি অভিন্ন ছিল এবং ইন্টারফেসের সাথে আপনাকে অবশ্যই সেগুলি পুনরায় লিখতে হবে


1
আপনাদের উদাহরণ একাধিক উত্তরাধিকার, তাই কি সমস্যা হয় বর্ণা না আপনি সমাধান বের করার চেষ্টা? সত্যিকারের একাধিক উত্তরাধিকার উদাহরণ প্রদর্শিত হবে class a : b, c(কোনও প্রয়োজনীয় চুক্তি ছিদ্র বাস্তবায়ন)। সম্ভবত আপনার উদাহরণগুলি কি সহজতর হয়েছে?
এমব্যাবকক

0

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

আমি উপর নির্মাণ IFirst, ISecond, First, Second, FirstAndSecond, পদ্ধতি যেমন প্রশ্নে উপহার দেওয়া হয়েছিল। আমি নমুনা কোডটি কমিয়ে আনি IFirst, যেহেতু প্যাটার্নটি ইন্টারফেস / এমআই বেস শ্রেণীর সংখ্যা নির্বিশেষে একই থাকে।

ধরা যাক, এমআই এর সাথে Firstএবং Secondউভয়ই একই বেস শ্রেণি থেকে প্রাপ্ত হবে BaseClass, কেবলমাত্র পাবলিক ইন্টারফেস উপাদানগুলি ব্যবহার করেBaseClass

এই প্রকাশ করা যেতে পারে, এর একটি ধারক রেফারেন্স যোগ করে BaseClassFirstএবং Secondবাস্তবায়ন:

class First : IFirst {
  private BaseClass ContainerInstance;
  First(BaseClass container) { ContainerInstance = container; }
  public void FirstMethod() { Console.WriteLine("First"); ContainerInstance.DoStuff(); } 
}
...

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

class BaseClass {
  protected void DoStuff();
}

abstract class First : IFirst {
  public void FirstMethod() { DoStuff(); DoSubClassStuff(); }
  protected abstract void DoStuff(); // base class reference in MI
  protected abstract void DoSubClassStuff(); // sub class responsibility
}

সি # নেস্টেড ক্লাসগুলিকে তাদের ধারণকৃত ক্লাসগুলির সুরক্ষিত / ব্যক্তিগত উপাদানগুলিতে অ্যাক্সেস করার অনুমতি দেয়, তাই এটি Firstবাস্তবায়ন থেকে বিমূর্ত বিটগুলিকে লিঙ্ক করতে ব্যবহার করা যেতে পারে ।

class FirstAndSecond : BaseClass, IFirst, ISecond {
  // link interface
  private class PartFirst : First {
    private FirstAndSecond ContainerInstance;
    public PartFirst(FirstAndSecond container) {
      ContainerInstance = container;
    }
    // forwarded references to emulate access as it would be with MI
    protected override void DoStuff() { ContainerInstance.DoStuff(); }
    protected override void DoSubClassStuff() { ContainerInstance.DoSubClassStuff(); }
  }
  private IFirst partFirstInstance; // composition object
  public FirstMethod() { partFirstInstance.FirstMethod(); } // forwarded implementation
  public FirstAndSecond() {
    partFirstInstance = new PartFirst(this); // composition in constructor
  }
  // same stuff for Second
  //...
  // implementation of DoSubClassStuff
  private void DoSubClassStuff() { Console.WriteLine("Private method accessed"); }
}

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


0

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

public interface IPerson {
  int GetAge();
  string GetName();
}

public interface IGetPerson {
  IPerson GetPerson();
}

public static class IGetPersonAdditions {
  public static int GetAgeViaPerson(this IGetPerson getPerson) { // I prefer to have the "ViaPerson" in the name in case the object has another Age property.
    IPerson person = getPerson.GetPersion();
    return person.GetAge();
  }
  public static string GetNameViaPerson(this IGetPerson getPerson) {
    return getPerson.GetPerson().GetName();
  }
}

public class Person: IPerson, IGetPerson {
  private int Age {get;set;}
  private string Name {get;set;}
  public IPerson GetPerson() {
    return this;
  }
  public int GetAge() {  return Age; }
  public string GetName() { return Name; }
}

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


0

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

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