জাভা একাধিক উত্তরাধিকার


168

জাভার একাধিক উত্তরাধিকার সমস্যাগুলি কীভাবে সমাধান করবেন তা পুরোপুরি বোঝার প্রয়াসে আমার কাছে একটি ক্লাসিক প্রশ্ন রয়েছে যা আমার স্পষ্ট করা দরকার।

আমি ক্লাস আছে বলে দেয় Animalএই উপ শ্রেণীর হয়েছে Birdএবং Horseআমি একটি বর্গ করতে হবে Pegasusযা থেকে প্রসারিত করে Birdএবং Horseযেহেতু Pegasusউভয় পাখির এবং একটি ঘোড়া হয়।

আমি মনে করি এটি ক্লাসিক হীরা সমস্যা। এটিকে সমাধান করার সর্বোত্তম উপায়টি আমি কী থেকে বুঝতে পারি তা হল Animal, Birdএবং Horseক্লাসের ইন্টারফেসগুলি তৈরি করা এবং Pegasusসেগুলি থেকে প্রয়োগ করা।

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


6
আমি মনে করি আপনি ম্যানুয়ালি ক্লাস তৈরি করতে এবং সদস্য হিসাবে সংরক্ষণ করতে পারেন (উত্তরাধিকারের পরিবর্তে রচনা)। প্রক্সি ( docs.oracle.com/javase/7/docs/api/java/lang/reflect/Proxy.html ) শ্রেণীর সাথে এটি একটি বিকল্প হতে পারে, যদিও আপনার ইন্টারফেসেরও প্রয়োজন হবে।
গবার বকোস

4
@ র্যাম তারপরে বার্ডের আচরণের প্রবণতা বাড়ানো উচিত নয় যা এটি বিমান চালাতে সক্ষম করে। : ডি সমস্যার সমাধান
যোগেশ

11
যথাযথভাবে। কিভাবে একটি ইন্টারফেস CanFly সম্পর্কে। :-)
অবাক নারকেল

28
আমি মনে করি এটি ভুল পদ্ধতি। আপনার কাছে প্রাণী আছে - ঘোড়া, পাখি। এবং আপনার সম্পত্তি আছে - ফ্লাইং, কর্নিভোর। একটি পেগাসাস একটি ঘোড়া বার্ড নয় এটি উড়তে পারে এমন একটি ঘোড়া। বৈশিষ্ট্য ইন্টারফেসে থাকা উচিত। তাই public class Pegasus extends Horse implements Flying
বোরিস দ্য স্পাইডার

12
আমি বুঝতে পেরেছি কেন আপনি এটি ভুল বলে মনে করেন এবং জীববিজ্ঞানের নিয়ম মেনে চলেন না এবং আপনার উদ্বেগের প্রশংসা করুন তবে আমার যে প্রোগ্রামটি তৈরি করতে হবে তা বাস্তবায়নের জন্য ব্যাংকগুলির সাথে আমার সম্পর্কটি সর্বোত্তম পন্থা ছিল। যেহেতু আমি আমার আসল সমস্যাগুলি পোস্ট করতে চাইনি যেহেতু এটি নিয়মের বিরুদ্ধেই আমি উদাহরণটি কিছুটা পরিবর্তন করেছি। ধন্যবাদ যদিও ...
শেলি

উত্তর:


115

আপনি প্রাণীর ক্লাস (জৈবিক অর্থের বর্গ), যেমন public interface Equidaeঘোড়া এবং public interface Avialaeপাখির জন্য ইন্টারফেস তৈরি করতে পারেন (আমি কোনও জীববিজ্ঞানী নই, সুতরাং পদগুলি ভুল হতে পারে)।

তারপরেও আপনি একটি তৈরি করতে পারেন

public class Bird implements Avialae {
}

এবং

public class Horse implements Equidae {}

এবং যদিও

public class Pegasus implements Avialae, Equidae {}

মন্তব্য থেকে যোগ করা:

সদৃশ কোড হ্রাস করার জন্য, আপনি এমন একটি বিমূর্ত ক্লাস তৈরি করতে পারেন যাতে আপনি প্রয়োগ করতে চান এমন প্রাণীদের বেশিরভাগ সাধারণ কোড থাকে।

public abstract class AbstractHorse implements Equidae {}

public class Horse extends AbstractHorse {}

public class Pegasus extends AbstractHorse implements Avialae {}

হালনাগাদ

আমি আরও একটি বিবরণ যোগ করতে চাই। যেমনব্রায়ান মন্তব্য , এটি ওপি ইতিমধ্যে জানত।

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


9
কোনটি ... ওপি বলেছে ঠিক সেটাই তারা জানে যে আপনি কিউতে পারেন
ব্রায়ান রোচ

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

8
আমি নিশ্চিত নই, আমি এখনও কোনও প্যাগাসাস দেখিনি। তবে সেই ক্ষেত্রে আমি একটি ব্যবহার করতে পছন্দ করব AbstractHorse, এটি জেব্রা বা অন্যান্য ঘোড়ার মতো প্রাণী তৈরিতেও ব্যবহার করা যেতে পারে।
মরিৎজ পিটারসেন

5
@ মরিৎসপিটারসন যদি আপনি সত্যিই বিমূর্তি পুনরায় ব্যবহার এবং অর্থবোধক নাম দেওয়ার দিকে যেতে চান AbstractEquidaeতবে সম্ভবত এর চেয়ে বেশি উপযুক্ত AbstractHorse। একটি জেব্রা একটি বিমূর্ত ঘোড়া প্রসারিত করা বিস্ময়কর হবে। ভাল উত্তর, যাইহোক।
আফসান্টোস

3
হাঁস-টাইপিং Duckপ্রয়োগ করে একটি শ্রেণি বাস্তবায়নও জড়িত Avialaeহবে?
mgarciaisaia

88

একসাথে বস্তুর সংমিশ্রণের জন্য দুটি মৌলিক পন্থা রয়েছে:

  • প্রথমটি হেরিটারেন্স । যেহেতু আপনি ইতিমধ্যে উত্তরাধিকারের সীমাবদ্ধতাগুলি চিহ্নিত করেছেন তার অর্থ আপনি এখানে যা প্রয়োজন তা করতে পারবেন না।
  • দ্বিতীয় রচনা । উত্তরাধিকার ব্যর্থ হওয়ায় আপনার রচনাটি ব্যবহার করা দরকার।

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

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

  • বার্ড প্রসারিত প্রাণী কার্যকরী IFlier
  • ঘোড়া প্রসারিত প্রাণী কার্যকরী IHerbivore, IQuadruped
  • পেগাসাস IHerbivore, আইক্যাড্রপড, আইফ্লেয়ারের প্রাণী সরঞ্জামগুলি প্রসারিত করে

এখন IFlierকেবল এটির মতো দেখাচ্ছে:

 interface IFlier {
     Flier getFlier();
 }

সুতরাং Birdএটির মতো দেখাচ্ছে:

 class Bird extends Animal implements IFlier {
      Flier flier = new Flier();
      public Flier getFlier() { return flier; }
 }

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

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

কৌশল রচনা প্যাটার্ন বিকল্প পদ্ধতির

আপনি কী এবং কী করছেন তার উপর নির্ভর করে একটি বিকল্প পদ্ধতির Animalভিত্তিটি হল বিভিন্ন স্তরের আচরণের তালিকা রাখতে বেস শ্রেণীর অভ্যন্তরীণ সংগ্রহ থাকতে পারে। সেক্ষেত্রে আপনি কৌশল প্যাটার্নের কাছাকাছি কিছু ব্যবহার করে শেষ করুন। কোডটি সরল করার ক্ষেত্রে এটি সুবিধা দেয় (উদাহরণস্বরূপ বা Horseসম্পর্কে কিছু জানার দরকার নেই ) তবে আপনি যদি ইন্টারফেসের পদ্ধতিকেও না করেন তবে পলিমারফিজম ইত্যাদির অনেক সুবিধা হারাবেন etc.QuadrupedHerbivore


অনুরূপ বিকল্পটি প্রকারের ক্লাসগুলিও ব্যবহার করা যেতে পারে, যদিও জাভাতে এটি ব্যবহার করা এতটা স্বাভাবিক নয় (আপনার কনভার্টার পদ্ধতিগুলি ব্যবহার করতে হবে) তবে এই ভূমিকাটি ধারণা পেতে কার্যকর হতে পারে: typeclassopedia.bitbucket.org
গ্যাবার

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

তবে getFlier()প্রতিটি পাখির জন্য পুনরায় খেলতে হবে।
এসএমইউসামশাহ

1
@ LifeH2O এগুলিকে ভাগ করে নেওয়া কার্যকারিতার ব্লকে ভাগ করুন তারপর সেগুলি দিন। অর্থাত আপনি থাকতে পারে MathsTeacherএবং EnglishTeacherউভয় inheriting Teacher, ChemicalEngineer, MaterialsEngineerইত্যাদি উত্তরাধিকারী EngineerTeacherএবং Engineerউভয় প্রয়োগ ComponentPersonতারপর একটি তালিকা রয়েছে Components, এবং তুমি কি তাদের সঠিক দিতে পারেন Componentযে জন্য গুলি Person। যেমন person.getComponent(Teacher.class), person.getComponent(MathsTeacher.class)ইত্যাদি
টিম বি

1
এটি সেরা উত্তর। থাম্বের নিয়ম হিসাবে, উত্তরাধিকার "হয়" এবং একটি ইন্টারফেস "ক্যান" উপস্থাপন করে। একটি পেগাসাস হ'ল একটি প্রাণী যা উড়ে বেড়াতে পারে। একটি পাখি উড়তে পারে এমন একটি প্রাণী। একটি ঘোড়া হাঁটতে পারে এমন একটি প্রাণী।
ছিনিয়ে নিন

43

আমার বোকা ধারণা আছে:

public class Pegasus {
    private Horse horseFeatures; 
    private Bird birdFeatures; 

   public Pegasus(Horse horse, Bird bird) {
     this.horseFeatures = horse;
     this.birdFeatures = bird;
   }

  public void jump() {
    horseFeatures.jump();
  }

  public void fly() {
    birdFeatures.fly();
  }
}

24
এটি কাজ করবে, তবে আমি সেই ধরণের পদ্ধতির (রে্যাপ্পার) পছন্দ করি না কারণ তখন মনে হয় পেগাসাস একটি ঘোড়া, পরিবর্তে এটি একটি ঘোড়া।
পাবলো লোজনো

ধন্যবাদ. আমি নিজের মতামত পোস্ট করতে সহায়তা করতে পারি না। আমি জানি যে এটি নির্বোধ, কিন্তু আমি কেন এটি বোকা তা
দেখিনি

3
এটি প্রায় টিম বি এর উত্তর থেকে রচনা পদ্ধতির একটি অপরিবর্তিত সংস্করণের মতো।
স্টিফান

1
এটি করার কম-বেশি স্বীকৃত উপায়, যদিও আপনার "আইজম্পস" এর মতো একটি "জাম্প" পদ্ধতিও থাকা উচিত যা ঘোড়া এবং পেগাসাস এবং আইফ্লিস দ্বারা প্রয়োগ করা হয় "ফ্লাই" পদ্ধতি যা বার্ড এবং পেগাসাস দ্বারা প্রয়োগ করা হয়।
ম্যাটসটি

2
@ পাবলো নো, একটি প্যাগাসাস হ্যাশ ফিচারস এবং হ'ল বার্ড ফিচারস। উত্তরের জন্য +1 কারণ এটি কোডটিকে সহজ রাখে, ক্লঙ্কিয়ার, ক্লাস-স্প্যানিং, যথাযথ জাভা সমাধানগুলির বিপরীতে।
জেনগুডাল

25

আমি কি হাঁসের টাইপিংয়ের ধারণাটি বলতে পারি ?

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

কৌশল ধরণে এই জাতীয় ধারণাটি ব্যবহার করা হয় । প্রদত্ত উদাহরণ আসলে আপনি দেখায় কিভাবে একটি হাঁসের উত্তরাধিকারী FlyBehaviourএবং QuackBehaviourএবং এখনও আছে হাঁসের হতে পারে যেমন RubberDuck, উড়তে করতে পারে। তারা প্রসারকে Duckএকটি Birdশ্রেণিবদ্ধও করতে পারত তবে তারা কিছুটা নমনীয়তা ছেড়ে দিত, কারণ প্রত্যেকে Duckউড়তে সক্ষম হত এমনকি দরিদ্রও RubberDuck


19

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


13

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


1
সচেতন থাকুন যদিও আপনার পাখি এবং ঘোড়া উভয়ের একটি ডিফল্ট পদ্ধতি রয়েছে তবে আপনি হীরা সমস্যাটি মোকাবেলা করতে পারেন এবং এটি আপনার পেগাসাস ক্লাসে পৃথকভাবে প্রয়োগ করতে হবে (বা সংকলক ত্রুটি পাবেন)।
মিক্কেল লাক্কে

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

12

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

তাহলে কি এমন ঘোড়ার মতো প্রাণী যা ঘোড়াও উড়তে পারে?

আমি একাধিক উত্তরাধিকার সম্পর্কে অনেক চিন্তাভাবনা করতাম, তবে এখন যেহেতু আমি ১৫ বছরেরও বেশি সময় ধরে প্রোগ্রাম করে চলেছি, আমি আর একাধিক উত্তরাধিকার প্রয়োগের বিষয়ে চিন্তা করি না।

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

অথবা

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


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

8

জাভাতে একাধিক উত্তরাধিকার সমস্যা নেই, কারণ এটির একাধিক উত্তরাধিকার নেই। আসল একাধিক উত্তরাধিকার সমস্যা (ডায়মন্ড সমস্যা) সমাধান করার জন্য এটি নকশা দ্বারা।

সমস্যা হ্রাস করার জন্য বিভিন্ন কৌশল রয়েছে। পাভেল পরামর্শ দেয় যে কম্পোজিট অবজেক্টটি সবচেয়ে অবিলম্বে অর্জনযোগ্য (মূলত কীভাবে এটি সি ++ পরিচালনা করে)। আমি জানিনা যে সি 3 লিনিয়ারাইজেশন (বা অনুরূপ) এর মাধ্যমে একাধিক উত্তরাধিকার জাভা ভবিষ্যতের কার্ডগুলিতে রয়েছে কিনা তবে আমি সন্দেহ করি।

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


6

আমি মনে করি এটি আপনার প্রয়োজনের উপর এবং আপনার কোডে কীভাবে আপনার প্রাণীর ক্লাস ব্যবহার করা যায় তার উপর নির্ভর করে।

আপনি যদি আপনার পেগাসাস বর্গের মধ্যে আপনার ঘোড়া এবং পাখি প্রয়োগের পদ্ধতি এবং বৈশিষ্ট্যগুলি ব্যবহার করতে সক্ষম হতে চান তবে আপনি পাগাস এবং একটি ঘোড়ার রচনা হিসাবে প্যাগাসাস প্রয়োগ করতে পারেন :

public class Animals {

    public interface Animal{
        public int getNumberOfLegs();
        public boolean canFly();
        public boolean canBeRidden();
    }

    public interface Bird extends Animal{
        public void doSomeBirdThing();
    }
    public interface Horse extends Animal{
        public void doSomeHorseThing();
    }
    public interface Pegasus extends Bird,Horse{

    }

    public abstract class AnimalImpl implements Animal{
        private final int numberOfLegs;

        public AnimalImpl(int numberOfLegs) {
            super();
            this.numberOfLegs = numberOfLegs;
        }

        @Override
        public int getNumberOfLegs() {
            return numberOfLegs;
        }
    }

    public class BirdImpl extends AnimalImpl implements Bird{

        public BirdImpl() {
            super(2);
        }

        @Override
        public boolean canFly() {
            return true;
        }

        @Override
        public boolean canBeRidden() {
            return false;
        }

        @Override
        public void doSomeBirdThing() {
            System.out.println("doing some bird thing...");
        }

    }

    public class HorseImpl extends AnimalImpl implements Horse{

        public HorseImpl() {
            super(4);
        }

        @Override
        public boolean canFly() {
            return false;
        }

        @Override
        public boolean canBeRidden() {
            return true;
        }

        @Override
        public void doSomeHorseThing() {
            System.out.println("doing some horse thing...");
        }

    }

    public class PegasusImpl implements Pegasus{

        private final Horse horse = new HorseImpl();
        private final Bird bird = new BirdImpl();


        @Override
        public void doSomeBirdThing() {
            bird.doSomeBirdThing();
        }

        @Override
        public int getNumberOfLegs() {
            return horse.getNumberOfLegs();
        }

        @Override
        public void doSomeHorseThing() {
            horse.doSomeHorseThing();
        }


        @Override
        public boolean canFly() {
            return true;
        }

        @Override
        public boolean canBeRidden() {
            return true;
        }
    }
}

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

সত্তা-উপাদান-সিস্টেম পদ্ধতির জন্য কয়েকটি সিউডো কোডটি দেখতে দেখতে এটি দেখতে পারে:

public void createHorse(Entity entity){
    entity.setComponent(NUMER_OF_LEGS, 4);
    entity.setComponent(CAN_FLY, false);
    entity.setComponent(CAN_BE_RIDDEN, true);
    entity.setComponent(SOME_HORSE_FUNCTIONALITY, new HorseFunction());
}

public void createBird(Entity entity){
    entity.setComponent(NUMER_OF_LEGS, 2);
    entity.setComponent(CAN_FLY, true);
    entity.setComponent(CAN_BE_RIDDEN, false);
    entity.setComponent(SOME_BIRD_FUNCTIONALITY, new BirdFunction());
}

public void createPegasus(Entity entity){
    createHorse(entity);
    createBird(entity);
    entity.setComponent(CAN_BE_RIDDEN, true);
}

4

আপনার একটি ইন্টারফেস শ্রেণিবিন্যাস থাকতে পারে এবং তারপরে নির্বাচিত ইন্টারফেস থেকে আপনার ক্লাস প্রসারিত করতে পারেন:

public interface IAnimal {
}

public interface IBird implements IAnimal {
}

public  interface IHorse implements IAnimal {
}

public interface IPegasus implements IBird,IHorse{
}

এবং তারপরে একটি নির্দিষ্ট ইন্টারফেস বাড়িয়ে প্রয়োজনীয় হিসাবে আপনার ক্লাসগুলি সংজ্ঞায়িত করুন:

public class Bird implements IBird {
}

public class Horse implements IHorse{
}

public class Pegasus implements IPegasus {
}

1
বা তিনি কেবল পারেন: পাবলিক ক্লাস পেগাসাস এনিমাল ইমপ্লিমেন্টস হর্স, বার্ড
ব্যাটম্যান

ওপি ইতিমধ্যে এই সমাধানটি সম্পর্কে সচেতন সে এটি করার বিকল্প উপায় খুঁজছে
যোগেশ

@Batman, অবশ্যই তিনি canm কিন্তু যদি সে অনুক্রমের প্রসারিত করতে চায় সে এই পদ্ধতির অনুসরণ করার প্রয়োজন হবে
richardtz

IBirdএবং এর পরিবর্তে IHorseবাস্তবায়ন IAnimalকরা উচিতAnimal
oliholz

@ যোগেশ, আপনি ঠিক বলেছেন। তিনি যে জায়গাতে বলেছেন সেখানে আমি তা উপেক্ষা করেছি। "নবাগত" হিসাবে আমার এখন কী করা উচিত, উত্তরটি মুছুন, বা সেখানে রেখে দেবেন? ধন্যবাদ,
রিচার্ড্টজ

4

হ্যাঁ, আপনার শ্রেণিটি কেবল অন্য 1 টির জন্য সাবক্লাস হতে পারে, তবে এখনও, আপনি যতটা ইন্টারফেস প্রয়োগ করতে পারেন, আপনি যেমন চান।

একটি পেগাসাস আসলে একটি ঘোড়া (এটি একটি ঘোড়ার একটি বিশেষ ঘটনা), যা উড়তে সক্ষম (যা এই বিশেষ ঘোড়ার "দক্ষতা")। অন্যদিকে, আপনি বলতে পারেন, পেগাসাস একটি পাখি, যা চলতে পারে এবং 4legged হয় - এটি সমস্ত নির্ভর করে, কোডটি লেখা আপনার পক্ষে কীভাবে সহজ।

আপনার ক্ষেত্রে যেমন আপনি বলতে পারেন:

abstract class Animal {
   private Integer hp = 0; 
   public void eat() { 
      hp++; 
   }
}
interface AirCompatible { 
   public void fly(); 
}
class Bird extends Animal implements AirCompatible { 
   @Override
   public void fly() {  
       //Do something useful
   }
} 
class Horse extends Animal {
   @Override
   public void eat() { 
      hp+=2; 
   }

}
class Pegasus extends Horse implements AirCompatible {
   //now every time when your Pegasus eats, will receive +2 hp  
   @Override
   public void fly() {  
       //Do something useful
   }
}

3

ইন্টারফেস একাধিক উত্তরাধিকার অনুকরণ করে না। জাভা নির্মাতারা একাধিক উত্তরাধিকারকে ভুল বলে মনে করেছিলেন, তাই জাভাতে এমন কোনও জিনিস নেই।

আপনি যদি দুটি শ্রেণীর কার্যকারিতা এক সাথে সংযুক্ত করতে চান - অবজেক্ট রচনাটি ব্যবহার করুন। অর্থাত

public class Main {
    private Component1 component1 = new Component1();    
    private Component2 component2 = new Component2();
}

এবং আপনি যদি কিছু পদ্ধতি প্রকাশ করতে চান তবে সেগুলি সংজ্ঞায়িত করুন এবং তাদেরকে সংশ্লিষ্ট নিয়ামকের কাছে কলটি অর্পণ করুন।

এখানে ইন্টারফেস কার্যকর হতে পারে - যদি Component1ইন্টারফেস Interface1এবং Component2প্রয়োগগুলি প্রয়োগ করে তবে Interface2আপনি সংজ্ঞায়িত করতে পারেন

class Main implements Interface1, Interface2

যাতে আপনি স্থান পরিবর্তন করতে পারেন যেখানে প্রসঙ্গটি এটির অনুমতি দেয়।

সুতরাং আমার দৃষ্টিতে আপনি হীরা সমস্যায় পড়তে পারবেন না।


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

3

আপনি ইতিমধ্যে সচেতন থাকবেন যে জাভাতে ক্লাসের একাধিক উত্তরাধিকার সম্ভব নয়, তবে ইন্টারফেসের মাধ্যমে এটি সম্ভব। আপনি রচনা নকশা প্যাটার্ন ব্যবহার বিবেচনা করতে পারেন।

আমি কয়েক বছর আগে রচনা নিয়ে একটি বিস্তৃত নিবন্ধ লিখেছিলাম ...

/codereview/14542/multiple-inheritance-and-composition-with-java-and-c-updated


3
  1. নির্ধারণ ইন্টারফেসগুলি ক্ষমতা সংজ্ঞা জন্য। আপনি একাধিক দক্ষতার জন্য একাধিক ইন্টারফেস সংজ্ঞায়িত করতে পারেন। এই ক্ষমতাগুলি নির্দিষ্ট প্রাণী বা পাখি দ্বারা প্রয়োগ করা যেতে পারে
  2. উত্তরাধিকার ব্যবহার করুনস্থিতিশীল এবং অ-প্রকাশ্য ডেটা / পদ্ধতিগুলি ভাগ করে ক্লাসগুলির মধ্যে সম্পর্ক স্থাপনের জন্য ।
  3. গতিশীলভাবে ক্ষমতা যুক্ত করতে ডেকরেটর_প্যাটার্ন ব্যবহার করুন। এটি আপনাকে উত্তরাধিকারের শ্রেণি এবং সংমিশ্রনের সংখ্যা হ্রাস করতে দেয়।

আরও ভাল বোঝার জন্য নীচের উদাহরণটি দেখুন

সজ্জিত প্যাটার্ন কখন ব্যবহার করবেন?


2

জটিলতা হ্রাস করতে এবং ভাষা সরল করতে একাধিক উত্তরাধিকার জাভাতে সমর্থিত নয়।

A, B এবং C তিনটি শ্রেণীর এমন একটি দৃশ্য বিবেচনা করুন। সি শ্রেণি উত্তরাধিকার সূত্রে এ এবং বি ক্লাস। যদি এ এবং বি ক্লাসগুলির একই পদ্ধতি থাকে এবং আপনি শিশু শ্রেণীর অবজেক্ট থেকে এটি কল করেন তবে এ বা বি শ্রেণীর কল পদ্ধতিতে দ্বিপাক্ষিকতা থাকবে।

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

class A {  
    void msg() {
        System.out.println("From A");
    }  
}

class B {  
    void msg() {
        System.out.println("From B");
    }  
}

class C extends A,B { // suppose if this was possible
    public static void main(String[] args) {  
        C obj = new C();  
        obj.msg(); // which msg() method would be invoked?  
    }
} 

2

জাভাতে একাধিক উত্তরাধিকারের সমস্যা সমাধানের জন্য ইন্টারফেস ব্যবহার করা হয়

জে 2 ইই (কোর জেভিএ) জনাব কেভিআর পৃষ্ঠা 51 নোটস

দিন - 27

  1. ইন্টারফেসগুলি মূলত ব্যবহারকারীর সংজ্ঞায়িত ডেটা ধরণের বিকাশ করতে ব্যবহৃত হয়।
  2. ইন্টারফেসের ক্ষেত্রে আমরা একাধিক উত্তরাধিকারের ধারণা অর্জন করতে পারি।
  3. ইন্টারফেসের সাহায্যে আমরা বহুবর্ষ, গতিশীল বাঁধাই ধারণাটি অর্জন করতে পারি এবং সেইজন্য আমরা মেমরির স্থান এবং সম্পাদনের সময়ের পরিবর্তে একটি জাভা প্রোগ্রামের কার্যকারিতা উন্নত করতে পারি।

একটি ইন্টারফেস হল এমন একটি নির্মাণ যা বিশুদ্ধরূপে সংজ্ঞায়িত পদ্ধতিগুলির সংকলন বা একটি ইন্টারফেস খাঁটি বিমূর্ত পদ্ধতিগুলির সংকলন।

[...]

দিন - 28:

শ্রেণিতে ইন্টারফেসের বৈশিষ্ট্যগুলি পুনরায় ব্যবহার করার জন্য সিনট্যাক্স -১:

[abstract] class <clsname> implements <intf 1>,<intf 2>.........<intf n>
{
    variable declaration;
    method definition or declaration;
};

উপরের সিনট্যাক্স ক্লসনেমে ক্লাসের নাম উপস্থাপন করা হয় যা ইন্টারফেসের 'এন' নম্বর থেকে বৈশিষ্ট্যগুলি উত্তরাধিকার সূত্রে প্রাপ্ত হয়। 'ইমপ্লিমেন্টস' এমন একটি কীওয়ার্ড যা ডাইরেক্ট ক্লাসে ইন্টারফেস (গুলি) এর বৈশিষ্ট্যগুলি উত্তরাধিকারী করার জন্য ব্যবহৃত হয়।

[...]

সিনট্যাক্স -২ অন্য ইন্টারফেসে 'এন' ইন্টারফেসের উত্তরাধিকার সূত্র:

interface <intf 0 name> extends <intf 1>,<intf 2>.........<intf n>
{     
    variable declaration cum initialization;
    method declaration;
};

[...]

সিনট্যাক্স-3:

[abstract] class <derived class name> extends <base class name> implements <intf 1>,<intf 2>.........<intf n>
{
  variable declaration;
  method definition or declaration;
};
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.