c# - হিন্দু উত্তরাধিকার আইন সম্পত্তি বন্টন




সি#একাধিক উত্তরাধিকার (11)

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

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

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(); }
}

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

একাধিক বিদ্যমান ক্লাসগুলিকে এক নতুন শ্রেণীতে প্রবেশ করার উপায় আছে যেমন C ++ তে সম্ভব?

সম্ভবত কোড প্রজন্মের ব্যবহার করে কোন সমাধান আছে?

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

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

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

সম্পাদনা

সম্ভবত এটি একটি বাস্তব উদাহরণ বিবেচনা করা ভাল হবে:

আপনার একটি বিদ্যমান বর্গ রয়েছে (যেমন একটি টেক্সট ভিত্তিক TCP ক্লায়েন্ট আইটিএক্সটিপিপি ক্লায়েন্টের উপর ভিত্তি করে) যা আপনি ইতিমধ্যে আপনার প্রোজেক্টের ভিতরে বিভিন্ন অবস্থানে ব্যবহার করেন। উইন্ডোজ ফর্ম ডেভেলপারদের জন্য সহজেই অ্যাক্সেসযোগ্য হওয়ার জন্য আপনার ক্লাসের একটি উপাদান তৈরি করার প্রয়োজন বোধ করা হচ্ছে।

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

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

  2. TextTcpClient থেকে উত্তরাধিকারী একটি নতুন বর্গ লিখুন এবং যেকোনভাবে IComponent প্রয়োগ করুন (আসলে এটি এখনও চেষ্টা করেনি)।

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

দ্বন্দ্ব এড়ানোর জন্য কোড প্রজন্মের দ্বারা এটি করা যেতে পারে যেখানে ফলাফলটি পরে পরিবর্তিত হতে পারে তবে হাত দ্বারা এটি টাইপ করা গাধাটির বিশুদ্ধ ব্যথা।


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

সি # এবং .নেট সিএলআর এমআইকে বাস্তবায়িত করেনি কারণ তারা সি #, ভিবিএনেট এবং অন্যান্য ভাষার মধ্যে কীভাবে কাজ করবে তা শেষ করে নি, কারণ এটি "উৎসটিকে আরো জটিল করে তুলবে না"

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

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

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


C # 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
}

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

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; }
}

এই কাঠামো কোড পুনঃব্যবহারযোগ্য ব্লক উপলব্ধ করা হয় এবং, অবশ্যই, কিভাবে OOP কোড লেখা উচিত?

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

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; }
}

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

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

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

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


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

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

আমার ক্ষেত্রে আমি এই বর্গটি করতে চেয়েছিলাম b: ফরম (windows.forms yep) ক্লাস c: b {}

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


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

আমি এই বিষয়ে আরও বিস্তারিতভাবে ব্লগ করেছি - যদিও উত্তরাধিকারের শর্তে ইচ্ছাকৃতভাবে অতিরিক্ত অর্থোপার্জনের প্রসঙ্গে।

আমি C # কম্পাইলারের মধ্যে এটি প্রয়োগ করা যায়নি কেন কোন কারণ নেই - কিন্তু এটি ভাষা জটিলতার আরেকটি বিট ...


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


একাধিক উত্তরাধিকার প্রশ্ন (এমআই) সময়ে সময়ে পপ আপ, যেহেতু আমি একটি পদ্ধতি যোগ করতে চাই যা রচনা প্যাটার্ন সঙ্গে কিছু সমস্যা ঠিকানা।

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

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

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

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
}

C # নেস্টেড ক্লাসগুলিকে তাদের ধারণকারী ক্লাসগুলির সুরক্ষিত / ব্যক্তিগত উপাদানগুলিতে অ্যাক্সেস করার অনুমতি দেয়, তাই এটি 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"); }
}

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


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

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


যদি Y থেকে Y উত্তরাধিকার সূত্রে প্রাপ্ত হয়, তবে এটি দুটি কিছুটা আংশিক প্রভাব রয়েছে:

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

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


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

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

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

 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();
         }
     }


 }

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







multiple-inheritance