একটি ক্লাসে একই পদ্ধতি সহ দুটি ইন্টারফেস প্রয়োগ করা। কোন ইন্টারফেস পদ্ধতি ওভাররাইড করা হয়?


235

একই পদ্ধতির নাম এবং স্বাক্ষর সহ দুটি ইন্টারফেস। তবে একটি একক শ্রেণীর দ্বারা প্রয়োগ করা হয়েছে তবে সংকলকটি কোন ইন্টারফেসের জন্য কোন পদ্ধতিটি সনাক্ত করবে?

উদা:

interface A{
  int f();
}

interface B{
  int f();
}

class Test implements A, B{   
  public static void main(String... args) throws Exception{   

  }

  @Override
  public int f() {  // from which interface A or B
    return 0;
  }
}   

উত্তর:


337

যদি কোনও প্রকার দুটি ইন্টারফেস প্রয়োগ করে এবং প্রত্যেকটি interfaceএমন একটি পদ্ধতি নির্ধারণ করে যা স্বতন্ত্র স্বাক্ষরযুক্ত থাকে, তবে কার্যত কেবলমাত্র একটি পদ্ধতি রয়েছে এবং সেগুলি পার্থক্যযোগ্য নয়। যদি, বলুন, দুটি পদ্ধতির দ্বন্দ্বপূর্ণ রিটার্নের ধরন রয়েছে তবে এটি সংকলন ত্রুটি হবে। এটি উত্তরাধিকার, পদ্ধতি ওভাররাইডিং, গোপনীয়তা এবং ঘোষণার সাধারণ নিয়ম এবং এটি 2 উত্তরাধিকার সূত্রে প্রাপ্ত interfaceপদ্ধতিগুলির মধ্যেই নয় , এমনকি একটি interfaceএবং একটি দুর্দান্ত classপদ্ধতি বা জেনেরিকের ধরণের ক্ষয়ের কারণে কেবল দ্বন্দ্বের ক্ষেত্রেও সম্ভব হয়।


সামঞ্জস্যতা উদাহরণ

এখানে একটি উদাহরণ রয়েছে যেখানে আপনার interface Giftএকটি present()পদ্ধতি রয়েছে, যার একটি পদ্ধতি রয়েছে (যেমন উপহার উপস্থাপন করে), এবং একটিও interface Guestরয়েছে যার একটি present()পদ্ধতিও রয়েছে (যেমন, অতিথি উপস্থিত আছেন এবং অনুপস্থিত নেই)।

Presentable johnnyউভয় একটি Giftএবং একটি Guest

public class InterfaceTest {
    interface Gift  { void present(); }
    interface Guest { void present(); }

    interface Presentable extends Gift, Guest { }

    public static void main(String[] args) {
        Presentable johnny = new Presentable() {
            @Override public void present() {
                System.out.println("Heeeereee's Johnny!!!");
            }
        };
        johnny.present();                     // "Heeeereee's Johnny!!!"

        ((Gift) johnny).present();            // "Heeeereee's Johnny!!!"
        ((Guest) johnny).present();           // "Heeeereee's Johnny!!!"

        Gift johnnyAsGift = (Gift) johnny;
        johnnyAsGift.present();               // "Heeeereee's Johnny!!!"

        Guest johnnyAsGuest = (Guest) johnny;
        johnnyAsGuest.present();              // "Heeeereee's Johnny!!!"
    }
}

উপরের স্নিপেট সংকলন এবং রান।

নোট করুন যে শুধুমাত্র একটি @Override প্রয়োজনীয় আছে !!! । এটি কারণ Gift.present()এবং Guest.present()" @Override-প্রসূত" ( জেএলএস 8.4.2 )।

সুতরাং, johnny কেবলমাত্র একটির বাস্তবায়ন রয়েছে present()এবং আপনি কীভাবে আচরণ করবেন johnnyতা বিবেচনাধীন নয় , একটি Giftহিসাবে বা হিসাবে হিসাবে Guest, অনুরোধ করার জন্য কেবল একটি পদ্ধতি রয়েছে।


অসামঞ্জস্যতার উদাহরণ

দুটি উত্তরাধিকারসূত্রে প্রাপ্ত পদ্ধতিটি @Overrideঅপরিহার্য নয় এমন একটি উদাহরণ এখানে :

public class InterfaceTest {
    interface Gift  { void present(); }
    interface Guest { boolean present(); }

    interface Presentable extends Gift, Guest { } // DOES NOT COMPILE!!!
    // "types InterfaceTest.Guest and InterfaceTest.Gift are incompatible;
    //  both define present(), but with unrelated return types"
}

এটি আরও পুনর্ব্যক্ত করেছে যে উত্তরাধিকার সূত্রে সদস্যদের interfaceসদস্য ঘোষণার সাধারণ নিয়ম মেনে চলতে হবে। এখানে আমাদের রয়েছে Giftএবং বেমানান রিটার্নের প্রকারগুলি Guestসংজ্ঞায়িত করা হয়েছে present(): একে voidঅপরকে boolean। একই কারণে তুমি পারবে না যে একটি void present()এবং একটি boolean present()এক ধরনের, একটি সংকলন ভুলবশত এই উদাহরণে ফলাফল নেই।


সারসংক্ষেপ

আপনি যে পদ্ধতিগুলি @Overrideযথাযথ, উত্তরাধিকারসূত্রে প্রাপ্ত এবং লুকিয়ে থাকা পদ্ধতির স্বাভাবিক প্রয়োজনীয়তার সাপেক্ষে উত্তরাধিকারী হতে পারেন । যেহেতু তারা হয় @Override -equivalent, কার্যকরীভাবে সেখানে বাস্তবায়ন শুধুমাত্র একটি পদ্ধতি, এবং এইভাবে সেখানে পার্থক্য / থেকে নির্বাচন করার কিছুই নেই।

@Overrideসংকলকটি কোন ইন্টারফেসের জন্য কোন পদ্ধতিটি তা সনাক্ত করতে হবে না, কারণ তারা একবার- সুক্ষ্ম হওয়ার জন্য দৃ are় সংকল্পবদ্ধ হয়ে গেলে তারা একই পদ্ধতি।

সম্ভাব্য অসুবিধাগুলি সমাধান করা খুব কঠিন কাজ হতে পারে তবে এটি সম্পূর্ণরূপে অন্য একটি সমস্যা।

তথ্যসূত্র


ধন্যবাদ - এটি সহায়ক ছিল। যাইহোক, আমার
বেমানানতা

2
বিটিডাব্লু defaultজাভা ৮-তে পদ্ধতির সহায়তায় এটি সামান্য পরিবর্তন হয়েছে
পিটার ল্যারি

সম্ভাব্য অসুবিধাগুলি সমাধানের জন্য যৌগিক শ্রেণিগুলি কৌশল হতে পারে :), তবে, আমার কখনও এ জাতীয় সমস্যা হয়নি, এবং এখনও এটি স্পষ্টতই এটি ঘটতে পারে।
কুম্ভ বিদ্যুৎ

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

1
একটি জাভা ডেভেলপার তোমার কিন্তু C # এ এই সত্যিই আরো চালাক: stackoverflow.com/questions/2371178/...
আমির Ziarati

25

এই প্রশ্নের সদৃশ হিসাবে চিহ্নিত করা হয়েছিল /programming/24401064/understanding-and-solving-the-diamond-problems-in-java

একাধিক উত্তরাধিকার সমস্যা পেতে আপনার জাভা 8 দরকার, তবে এটি এখনও ডায়ামনের সমস্যা নয়।

interface A {
    default void hi() { System.out.println("A"); }
}

interface B {
    default void hi() { System.out.println("B"); }
}

class AB implements A, B { // won't compile
}

new AB().hi(); // won't compile.

জেবি নিজেট মন্তব্য হিসাবে আপনি এটি আমার ওভাররাইডিং ঠিক করতে পারেন।

class AB implements A, B {
    public void hi() { A.super.hi(); }
}

তবে আপনার সমস্যা নেই

interface D extends A { }

interface E extends A { }

interface F extends A {
    default void hi() { System.out.println("F"); }
}

class DE implement D, E { }

new DE().hi(); // prints A

class DEF implement D, E, F { }

new DEF().hi(); // prints F as it is closer in the heirarchy than A.

কি দারুন. এইটা আমার কাছে নতুন. তাদের জাভা 8 এ ডিফল্ট তৈরি করতে হয়েছিল কেন?
এরান মোরাড

1
ইন্টারফেসে নতুন পদ্ধতি যুক্ত করার সুবিধার্থে (বিশেষত ইন্টারফেসগুলি সংগ্রহ করে) b০% কোডবেস না ভেঙে।
তাসসোস বসুকোস

@ বোরাটসাগদিয়েভ সবচেয়ে বড় কারণ হ'ল বন্ধকে সমর্থন করা এবং আরও কার্যকর করা। সংগ্রহ.প্রবাহ () দেখুন। List.sort () docs.oracle.com/javase/8/docs/api/java/util/… এ দেখুন তারা নির্দিষ্ট তালিকাভুক্তি পরিবর্তন না করেই সমস্ত তালিকার জন্য একটি পদ্ধতি যুক্ত করেছে। তারা
কালেকশন.রেমওয়েফ

@ টাসসবাসৌকোস +1 বলছেন আপনার নিজের তালিকার নিজস্ব প্রয়োগ রয়েছে, এখন আপনি আপনার কোড পরিবর্তন না করেই মাইলিস্ট.স্ট্রিম () এটি বা মাইলিস্ট.সোর্ট () করতে পারেন
পিটার লরে

3
@ পিটারলাউরে: এবি সংকলন করবে না কারণ এটি ওভাররাইড hi()করতে হবে (অস্পষ্টতা ঠিক করতে)। উদাহরণস্বরূপ, A.super.hi()এটিকে ঠিক একইভাবে প্রয়োগ করা পছন্দ হিসাবে এটি প্রয়োগ করে
জেবি নিজেট

20

সংকলক হিসাবে যতদূর, এই দুটি পদ্ধতি অভিন্ন। উভয়ের বাস্তবায়ন হবে।

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


2
এটা তোলে ব্যাখ্যা দিয়েছে কেন জাভা আপনি অনুমতি দেয় না প্রসারিত একাধিক শ্রেণী
আর্থার রোনাল্ড

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

13

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

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


4

অজানা হিসাবে ইন্টারফেস প্রয়োগ করার চেষ্টা করুন।

public class MyClass extends MySuperClass implements MyInterface{

MyInterface myInterface = new MyInterface(){

/* Overrided method from interface */
@override
public void method1(){

}

};

/* Overrided method from superclass*/
@override
public void method1(){

}

}

4

ইন্টারফেস হিসাবে, আমরা কেবল পদ্ধতিগুলি ঘোষণা করছি, কংক্রিট শ্রেণি যা এই উভয় ইন্টারফেসকে বোঝে তা বাস্তবায়ন করে কেবল একটি পদ্ধতি আছে (যেমন আপনি বর্ণনা করেছেন উভয়টির রিটার্ন টাইপের একই নাম রয়েছে)। সুতরাং এটি নিয়ে কোনও সমস্যা হওয়া উচিত নয় You আপনি কংক্রিট শ্রেণিতে সেই পদ্ধতিটি নির্ধারণ করতে সক্ষম হবেন।

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

নীচের কোডটি দেখুন:

public interface InterfaceA {
  public void print();
}


public interface InterfaceB {
  public int print();
}

public class ClassAB implements InterfaceA, InterfaceB {
  public void print()
  {
    System.out.println("Inside InterfaceA");
  }
  public int print()
  {
    System.out.println("Inside InterfaceB");
    return 5;
  }
}

সংকলকটি যখন "পাবলিক শূন্য প্রিন্ট ()" পায় তখন এটি প্রথম ইন্টারফেসএতে দেখায় এবং তা পেয়ে যায় still তবে এটি সংকলন সময় ত্রুটি দেয় যে রিটার্ন টাইপটি ইন্টারফেসবি পদ্ধতির সাথে সামঞ্জস্যপূর্ণ নয়।

তাই এটি সংকলক জন্য haywire যায়।

এইভাবে, আপনি দুটি একই ইন্টারফেস একই নামের একটি পদ্ধতিযুক্ত হলেও ভিন্ন রিটার্নের ধরণের প্রয়োগ করতে পারবেন না।


3

ঠিক আছে যদি তারা উভয় একই হয় তবে তাতে কিছু আসে যায় না। এটি ইন্টারফেস পদ্ধতিতে একক কংক্রিট পদ্ধতিতে উভয়কেই প্রয়োগ করে।

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