জাভা - ইন্টারফেস প্রয়োগে পদ্ধতির নামের সংঘর্ষ


88

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

সি # তে, এটি সুস্পষ্ট ইন্টারফেস বাস্তবায়ন হিসাবে যাকে ডাকা হয় তাকে অতিক্রম করে। জাভাতে কোন সমান উপায় আছে?


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

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

4
আমি এই ক্লাস এবং পদ্ধতি কি জানতে আগ্রহী হতে হবে।
উরি

4
আমি এমন একটি মামলার মুখোমুখি হয়েছি যেখানে কোনও উত্তরাধিকার "ঠিকানা" শ্রেণি ব্যক্তি এবং ফার্ম ইন্টারফেস প্রয়োগ করে যার একটি getName () পদ্ধতিটি কেবল ডেটা মডেল থেকে স্ট্রিং ফিরিয়ে দেয়। একটি নতুন ব্যবসায়ের প্রয়োজনীয়তার সাথে উল্লেখ করা হয়েছে যে পার্সন.জেটনেম () একটি নামকে "উপাধি, প্রদত্ত নাম" হিসাবে ফর্ম্যাট করে return অনেক আলোচনার পরে ডাটাবেসে ডেটাটি পুনরায় গঠন করা হয়েছিল।
বেলউড

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

উত্তর:


75

না, জাভাতে এক শ্রেণিতে দুটি ভিন্ন পদ্ধতিতে একই পদ্ধতি প্রয়োগের কোনও উপায় নেই।

এটি অনেক বিভ্রান্তিকর পরিস্থিতিতে ডেকে আনতে পারে, এজন্য জাভা এটিকে অস্বীকার করেছেন।

interface ISomething {
    void doSomething();
}

interface ISomething2 {
    void doSomething();
}

class Impl implements ISomething, ISomething2 {
   void doSomething() {} // There can only be one implementation of this method.
}

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

class CompositeClass {
    ISomething class1;
    ISomething2 class2;
    void doSomething1(){class1.doSomething();}
    void doSomething2(){class2.doSomething();}
}

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

9
@ ভাস্কর, আপনি বৈধ পয়েন্ট করেছেন। আমার কাছে সেরা পরামর্শটি হ'ল সেই শ্রেণিতে একটি ISomething1 CompositeClass.asInterface1();এবং ISomething2 CompositeClass.asInterface2();পদ্ধতি যুক্ত করুন । তারপরে আপনি একটি বা অন্যটিকে যৌগিক শ্রেণীর বাইরে আসতে পারেন। যদিও এই সমস্যার কোনও দুর্দান্ত সমাধান নেই।
jjnguy

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

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

4
public long getCountAsLong() implements interface2.getCount {...}[ইন্টারফেসের ক্ষেত্রে longক্লাসের ব্যবহারকারীদের প্রত্যাশার প্রয়োজন থাকলে int] বা private void AddStub(T newObj) implements coolectionInterface.Add[ধরে collectionInterfaceনেওয়া একটি canAdd()পদ্ধতি আছে এবং এই শ্রেণীর সমস্ত দৃষ্টান্তের জন্য এটি ফিরে আসে false] এর মতো কিছু করার পক্ষে কী বিভ্রান্তি হবে ?
সুপারক্যাট

13

জাভাতে এটি সমাধান করার কোনও আসল উপায় নেই। আপনি অভ্যন্তরীণ ক্লাসগুলিকে কাজের মতো হিসাবে ব্যবহার করতে পারেন:

interface Alfa { void m(); }
interface Beta { void m(); }
class AlfaBeta implements Alfa {
    private int value;
    public void m() { ++value; } // Alfa.m()
    public Beta asBeta() {
        return new Beta(){
            public void m() { --value; } // Beta.m()
        };
    }
}

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


আপনি কি অভ্যন্তর শ্রেণির চেয়ে বেনাম শ্রেণি বলতে চান?
জায়েদ মাসুদ

4
@ জায়েদমাসুদ আমার অর্থ অভ্যন্তরীণ শ্রেণী, যেহেতু তারা ঘেরযুক্ত বস্তুর ব্যক্তিগত অবস্থানে প্রবেশ করতে পারে)। এই অভ্যন্তরীণ ক্লাসগুলি অবশ্যই বেনামেও থাকতে পারে।
gustafc

11

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

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

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


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

4
@ নাইটপুল আপনি যদি একাধিক লাইব্রেরি ব্যবহার করেন যা প্রত্যেকের জন্য আলাদা ইন্টারফেসের প্রয়োজন হয় তবে এখনও কোনও একক বস্তুর জন্য উভয় ইন্টারফেস প্রয়োগ করা প্রয়োজন হয় না; দুটি ভিন্ন ইন্টারফেসের প্রতিটি প্রত্যাবর্তনের জন্য আপনার কাছে অবজেক্টের অ্যাক্সেসর থাকতে পারে (এবং অন্তর্নিহিত লাইব্রেরির একটিতে অবজেক্টটি পাশ করার সময় উপযুক্ত অ্যাকসেসর কল করুন)।
মাইকেল অ্যারন সাফিয়ান

1

"শাস্ত্রীয়" জাভা সমস্যাটি আমার অ্যান্ড্রয়েড বিকাশকেও প্রভাবিত করে ...
কারণটি সহজ বলে মনে হচ্ছে: আপনার
আরও ফ্রেমওয়ার্ক / লাইব্রেরিগুলি ব্যবহার করতে হবে, আরও সহজেই জিনিসগুলি নিয়ন্ত্রণের বাইরে চলে যেতে পারে ...

আমার ক্ষেত্রে আমার একটি বুটস্প্রেপার অ্যাপ্লিকেশন ক্লাস রয়েছে android.app.
প্রয়োগ থেকে উত্তরাধিকার সূত্রে প্রাপ্ত , একই শ্রেণীর একীভূত হওয়ার জন্য MVVM কাঠামোর একটি প্ল্যাটফর্ম ইন্টারফেসও প্রয়োগ করা উচিত ।
পদ্ধতির সংঘর্ষটি একটি getString () পদ্ধতিতে ঘটেছিল , যা উভয় ইন্টারফেস দ্বারা ঘোষণা করা হয় এবং বিভিন্ন প্রসঙ্গে বিভিন্ন নেটওয়ার্ক প্রয়োগ করা উচিত।
ওয়ার্কআরাউন্ড (কুরুচিপূর্ণ..আইএমও) সমস্ত প্ল্যাটফর্ম বাস্তবায়নের জন্য একটি অভ্যন্তর শ্রেণি ব্যবহার করছেপদ্ধতিগুলি, কেবলমাত্র একটি গৌণ পদ্ধতির স্বাক্ষরের দ্বন্দ্বের কারণে ... কিছু ক্ষেত্রে, এই জাতীয় methodণ প্রাপ্ত পদ্ধতিটি মোটেই ব্যবহৃত হয় না (তবে প্রভাবিত প্রধান নকশা শব্দার্থবিজ্ঞান)।
আমি সি # স্টাইলের স্পষ্ট প্রসঙ্গ / নেমস্পেস ইঙ্গিতটি সহায়ক বলে সম্মত হতে চাই।


4
অ্যান্ড্রয়েড বিকাশের জন্য জাভা ব্যবহার শুরু না করা পর্যন্ত আমি কখনই বুঝতে পারিনি যে সি # কীভাবে চিন্তাশীল এবং বৈশিষ্ট্যযুক্ত। আমি সেই সি # বৈশিষ্ট্যগুলি সম্মানের জন্য নিয়েছি। জাভাতে অনেকগুলি বৈশিষ্ট্য নেই।
অভিশাপ শাকসবজি

1

আমার মনে যে একমাত্র সমাধানটি এসেছিল তা হ'ল রেফারিজ অবজেক্টগুলি যাকে আপনি মুভিযুক্ত ইন্টারফেসগুলি ইমপ্রেস করতে চান তার কাছে ব্যবহার করা।

উদাহরণস্বরূপ: ধরুন আপনার বাস্তবায়নের জন্য দুটি ইন্টারফেস রয়েছে

public interface Framework1Interface {

    void method(Object o);
}

এবং

public interface Framework2Interface {
    void method(Object o);
}

আপনি এগুলি দুটি ফ্যাসাডোর অবজেক্টগুলিতে আবদ্ধ করতে পারেন:

public class Facador1 implements Framework1Interface {

    private final ObjectToUse reference;

    public static Framework1Interface Create(ObjectToUse ref) {
        return new Facador1(ref);
    }

    private Facador1(ObjectToUse refObject) {
        this.reference = refObject;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof Framework1Interface) {
            return this == obj;
        } else if (obj instanceof ObjectToUse) {
            return reference == obj;
        }
        return super.equals(obj);
    }

    @Override
    public void method(Object o) {
        reference.methodForFrameWork1(o);
    }
}

এবং

public class Facador2 implements Framework2Interface {

    private final ObjectToUse reference;

    public static Framework2Interface Create(ObjectToUse ref) {
        return new Facador2(ref);
    }

    private Facador2(ObjectToUse refObject) {
        this.reference = refObject;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof Framework2Interface) {
            return this == obj;
        } else if (obj instanceof ObjectToUse) {
            return reference == obj;
        }
        return super.equals(obj);
    }

    @Override
    public void method(Object o) {
        reference.methodForFrameWork2(o);
    }
}

শেষের দিকে আপনি যে ক্লাসটি চেয়েছিলেন তার মতো কিছু করা উচিত

public class ObjectToUse {

    private Framework1Interface facFramework1Interface;
    private Framework2Interface facFramework2Interface;

    public ObjectToUse() {
    }

    public Framework1Interface getAsFramework1Interface() {
        if (facFramework1Interface == null) {
            facFramework1Interface = Facador1.Create(this);
        }
        return facFramework1Interface;
    }

    public Framework2Interface getAsFramework2Interface() {
        if (facFramework2Interface == null) {
            facFramework2Interface = Facador2.Create(this);
        }
        return facFramework2Interface;
    }

    public void methodForFrameWork1(Object o) {
    }

    public void methodForFrameWork2(Object o) {
    }
}

আপনি এখন আপনার ক্লাস "এক্সপোজ" করার জন্য getAs * পদ্ধতিগুলি ব্যবহার করতে পারেন


0

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


-1

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

public class MyClass{

    private String name;

    MyClass(String name){
        this.name = name;
    }

    public String getName(){
        return name;
    }
}

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

সি # এ এটি একটি ক্ষুধা হবে

public class MyClass : WBPInterface{

    private String name;

    String WBPInterface.getName(){
        return "MyWizzBangProcessor";
    }

    MyClass(String name){
        this.name = name;
    }

    public String getName(){
        return name;
    }
}

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

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

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