দুটি ক্লাস থেকে বাড়ানো


150

কিভাবে আমি এটি করতে পারব:

public class Main extends ListActivity , ControlMenu 

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


4
আপনি একসাথে দুই বা ততোধিক ক্লাস বাড়াতে পারবেন না। জাভাতে একাধিক উত্তরাধিকার অনুমোদিত নয়।
যোগসমা

উত্তর:


156

আপনি কেবল একটি একক শ্রেণি প্রসারিত করতে পারেন। এবং অনেক উত্স থেকে ইন্টারফেস প্রয়োগ করুন।

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

 public class CustomActivity extends Activity {

     private AnotherClass mClass;

     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         mClass = new AnotherClass(this);
     }

     //Implement each method you want to use.
     public String getInfoFromOtherClass()
     {
        return mClass.getInfoFromOtherClass();
     }
 }

এটিই আমি নিয়ে এসেছি সেরা সমাধান। আপনি উভয় শ্রেণি থেকে কার্যকারিতা পেতে পারেন এবং তবুও কেবল আসলে এক শ্রেণির হতে পারে।

অপূর্ণতাটি হ'ল আপনি একটি usingালাই ব্যবহার করে অভ্যন্তরীণ শ্রেণির ছাঁচে ফিট করতে পারবেন না।


2
আপনি দ্রুত ছিলেন :) আমি আপনার উত্তরটি আপনার কংক্রিটের উদাহরণের সাথে তুলনা করতে কিছু বিমূর্ত হিসাবে
ছড়িয়ে দেব

1
এটি একটি দুর্দান্ত বিকল্প, এবং ভবিষ্যতে আরও অনেক নমনীয়তা সরবরাহ করে।
ডেভিড সাউদার

1
আরও বেশি ওওপি সমাধানের জন্য @ এসসিবি সমাধান দেখুন
মূর্তি

আমি এখানে আরও সুনির্দিষ্ট উদাহরণ ব্যবহার করতে পারি। আমি নিশ্চিত নই বুঝতে পেরেছি.
নিও 42

54

কেন অভ্যন্তর শ্রেণি ব্যবহার করবেন না (বাসা)

class A extends B {
    private class C extends D {
        //Classes A , B , C , D accessible here 
    }
}

4
আন্তঃরাষ্ট্রীয় পদ্ধতির, বিশেষজ্ঞরা এই কৌশল সম্পর্কে কী মনে করেন? আমি এটি খনন করতে চাই।
টেকনিকুইস্ট

1
এটা কনভেনশনস দিয়ে ঠিক আছে?
টোটেন

2
একটিতে কাজ করার জন্য অভ্যন্তর শ্রেণি পেতে পারেনি Fragment। আমার ক্রিয়াকলাপটি অবশ্যই প্রসারিত হবে Fragment, যার অর্থ আমার একেবারে প্রয়োজন getView(), যা এটি অভ্যন্তরীণ শ্রেণীর অভ্যন্তরে থাকলে কাজ করবে না এবং সেখানে কোডটি যেখানে আমার কোড ব্যবহার করা দরকার ListActivity, তাই আমি দুবার প্রসারিত করতে পারি না, বা কোনও অভ্যন্তর শ্রেণি করতে পারি না এই উদাহরণে।
আজুরস্পট

এটি বিমূর্ত ক্লাসগুলি বাড়ানোর জন্য সেরা সমাধান যেখানে আপনার ইমপিমেন্টিং ক্লাসের ভেরিয়েবলগুলিতে অ্যাক্সেস প্রয়োজন need
টাকশী

45

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

বলুন যে আপনার আছে class Fooএবং class Barআপনি উভয়ই একটিতে প্রসারিত করার চেষ্টা করতে চান class FooBar। অবশ্যই, আপনি যেমন বলেছিলেন, আপনি এটি করতে পারবেন না:

public class FooBar extends Foo, Bar

মানুষ এর জন্য ইতিমধ্যে কিছু পরিমাণে কারণগুলিতে চলে গেছে। পরিবর্তে, interfacesউভয়ের জন্য লিখুন Fooএবং Barতাদের সমস্ত পাবলিক পদ্ধতি আবরণ। যেমন

public interface FooInterface {

    public void methodA();

    public int methodB();

    //...
} 

public interface BarInterface {

    public int methodC(int i);

    //...
}

এবং এখন আপেক্ষিক ইন্টারফেসগুলি তৈরি Fooএবং Barপ্রয়োগ করুন:

public class Foo implements FooInterface { /*...*/ }

public class Bar implements BarInterface { /*...*/ }

এখন, সঙ্গে class FooBar, আপনি উভয় বাস্তবায়ন করতে পারেনFooInterface এবং BarInterfaceএকটি Fooএবং Barঅবজেক্ট রাখার সময় এবং কেবল পদ্ধতিগুলি সোজা করার মাধ্যমে:

public class FooBar implements FooInterface, BarInterface {

    Foo myFoo;
    Bar myBar;

    // You can have the FooBar constructor require the arguments for both
    //  the Foo and the Bar constructors
    public FooBar(int x, int y, int z){
        myFoo = new Foo(x);
        myBar = new Bar(y, z);
    }

    // Or have the Foo and Bar objects passed right in
    public FooBar(Foo newFoo, Bar newBar){
        myFoo = newFoo;
        myBar = newBar;
    }

    public void methodA(){
        myFoo.methodA();
    }

    public int methodB(){
        return myFoo.methodB();
    }

    public int methodC(int i){
        return myBar.methodC(i);
    }

    //...

}

এই পদ্ধতির জন্য বোনাস, এটি FooBar বস্তু উভয়ের ছাঁচ ফিট FooInterfaceএবং BarInterface। এর অর্থ এটি পুরোপুরি ঠিক আছে:

FooInterface testFoo;
testFoo = new FooBar(a, b, c);
testFoo = new Foo(a);

BarInterface testBar;
testBar = new FooBar(a, b, c);
testBar = new Bar(b, c);

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


6
এটি সেরা উত্তর
ব্যবহারকারী 3290180

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

যদি আমাদের "ঘন ঘন" নতুন ক্লাস তৈরি করতে হয় এবং সেই ক্লাসগুলির প্রত্যেকটি উভয় ইন্টারফেস প্রয়োগ করে? তারপরে, প্রতিটি ক্লাসে আমাদের এই বয়লারপ্লেট বাস্তবায়নগুলি পুনরাবৃত্তি করতে হবে। কোনও শ্রেণি দুটি ব্যবহারের সেট "প্রয়োগ" করার আরও ভাল উপায় কী?
মাস্টারজয়ে 2

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

37

আপনি ইন্টারফেস ব্যবহার করতে চাইবেন। সাধারণত, ডায়মন্ড সমস্যার কারণে একাধিক উত্তরাধিকার খারাপ:

abstract class A {
 abstract string foo();
}

class B extends A {
 string foo () { return "bar"; }
}

class C extends A  {
 string foo() {return "baz"; }
}

class D extends B, C {
 string foo() { return super.foo(); } //What do I do? Which method should I call?
}

সি ++ এবং অন্যদের কাছে এটি সমাধানের কয়েকটি উপায় রয়েছে, যেমন

string foo() { return B::foo(); }

তবে জাভা কেবল ইন্টারফেস ব্যবহার করে।

ইন্টারফেসে জাভা ট্রেলগুলির দুর্দান্ত ভূমিকা রয়েছে: http://download.oracle.com/javase/tutorial/java/concepts/interface.html আপনি সম্ভবত এন্ড্রয়েড এপিআইতে সবিস্তারে ডুব দেওয়ার আগে এটি অনুসরণ করতে চান।


24
আমি বুঝতে পারিনি কেন হীরা সমস্যাটি আসলে এমন সমস্যা যা একাধিক উত্তরাধিকার রোধ করে। একই নামের সাথে বিরোধী পদ্ধতি থাকলে সংক্ষেপক কেন কেবল অভিযোগ করতে পারবেন না?
পিট

1
পর্যাপ্ত বুদ্ধিমান সংকলকগুলির জন্য, এটি নয়। সংকলক স্তরে এটি সমাধান করা সম্ভব এবং সত্যই সি ++ এটি দিয়ে virtual class। কম্পাইলার এবং বিকাশকারী উভয়ের জন্য এটি করা অনেক সতর্কতা এবং সতর্কতা সহ আসে।
ডেভিড সাউদার

1
দুটি ইন্টারফেসে একই ডিফল্ট পদ্ধতি সম্পর্কে কীভাবে? এটি হীরা সমস্যার আরেকটি উদাহরণ, যা জাভা পরিচালনা করতে পারে।
লাজোস মেসারোস

1
@ MészárosLajos কিন্তু আপনি superউত্তরাধিকার সূত্রে প্রাপ্ত কোনও পদ্ধতিতে কল করবেন না । ঠিক আছে, আপনি পারেন তবে আপনাকে অনুরোধ করার জন্য ইন্টারফেস পদ্ধতিটি নির্দিষ্ট করতে হবে (এবং এটি অবশ্যই defaultইন্টারফেস প্রয়োগের ক্ষেত্রে কীওয়ার্ডটি ব্যবহার করতে হবে ) । একটি উদাহরণ হ'ল: MyIFace.super.foo()যেখানে মাইফেস একটি ইন্টারফেস। আপনি দেখতে পাচ্ছেন এক্সিকিউট করার জন্য ইন্টারফেসের পদ্ধতিটি সংজ্ঞায়িত করা হয়েছে এবং ডায়মন্ড সমস্যা সম্পূর্ণভাবে এড়িয়ে চলে। যদি আপনি প্রসারিত করেন MyClass1এবং MyClass2, উভয় শ্রেণীর একটি থাকে foo(), এবং কল করেন super.foo()তবে সংকলকটি হীরা সমস্যা দ্বারা নিক্ষেপ করা হবে।
জেডিএসওয়েটবিট

আপনি ফিরতে পারবেন না "bar"বা "baz"পদ্ধতি ধরণের সাথে void। যাইহোক, ভাল ব্যাখ্যা এক্সডি
xdevs23

22

হ্যাঁ, সবাই যেমন লিখেছেন, আপনি জাভাতে একাধিক উত্তরাধিকার করতে পারবেন না। আপনার যদি দুটি ক্লাস থাকে যা থেকে আপনি কোডটি ব্যবহার করতে চান, আপনি সাধারণত কেবল একটি সাবক্লাস (ক্লাস বলুন A) করুন। শ্রেণীর জন্য B, আপনি এটির গুরুত্বপূর্ণ পদ্ধতিগুলি একটি ইন্টারফেসে BInterface(কুৎসিত নাম, তবে আপনি ধারণাটি পেয়েছেন) এ বিমূর্ত করে , তারপরে বলুন Main extends A implements BInterface। ভিতরে, আপনি শ্রেণীর কোনও অবজেক্ট ইনস্ট্যান্ট করতে Bএবং BInterfaceএর সম্পর্কিত ফাংশনগুলিকে কল করে সমস্ত পদ্ধতি বাস্তবায়ন করতে পারেনB

এটি " Mainএখনকার একটি" সম্পর্কের সাথে "হ'ল-এ" সম্পর্কের পরিবর্তন করে কারণ আপনার এখনকার একটি Aতবে এর একটি রয়েছে B। আপনার ব্যবহারের ক্ষেত্রে নির্ভর করে আপনি এমনকি BInterfaceআপনার Aশ্রেণি থেকে অপসারণ করে সেই পরিবর্তনটি স্পষ্ট করে তুলতে পারেন এবং পরিবর্তে আপনার বি অবজেক্টটি সরাসরি অ্যাক্সেস করার জন্য একটি পদ্ধতি সরবরাহ করতে পারেন।


এটি সবচেয়ে সুস্পষ্ট ব্যাখ্যা এবং সহজে বোঝার সহজ ব্যাখ্যা। দয়া করে আরও বেশি কিছু
আলগোরিণী

12

একটি ইন্টারফেস তৈরি করুন। জাভার একাধিক উত্তরাধিকার নেই।

http://csis.pace.edu/~bergin/patterns/multipleinheritance.html


9
অজু কেন ডাউনটা? আমি বোঝানো যাচ্ছিলাম না, আমি কেবল তার জন্য কিছু ক্লাস তৈরি করার আগে কিছুটা পড়া এবং সমস্যাটি নিয়ে তার নিজের চিন্তাভাবনা করার সামর্থ্য ছিল বলে মনে করি
slandau

6

জাভা একাধিক উত্তরাধিকার সমর্থন করে না, তবে আপনি দুটি বা ততোধিক ইন্টারফেস প্রয়োগের চেষ্টা করতে পারেন।


4

হ্যাঁ. অপবাদ ঠিক আছে। জাভা বেশ কয়েকটি ক্লাস থেকে প্রসারিত হতে দেয় না।

আপনি যা চান সম্ভবত public class Main extends ListActivity implements ControlMenu । আমি অনুমান করছি আপনি একটি তালিকা তৈরির চেষ্টা করছেন।

আশা করি এইটি কাজ করবে.


3

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

উদাহরণস্বরূপ, আপনি একটি বিমূর্ত শ্রেণি এবং একটি ইন্টারফেস তৈরি করতে পারেন:

public abstract class FatherClass {

    abstract void methodInherit() {
        //... do something
    }
}

public interface InterfaceWithDefaultsMethods {
    default void anotherMethod() {
        //... do something
        //... maybe a method with a callable for call another function.
    }
}

সুতরাং, এর পরে, আপনি উভয় ক্লাস প্রসারিত এবং প্রয়োগ করতে পারেন এবং উভয় পদ্ধতি ব্যবহার করতে পারেন।

public class extends FatherClass implements InterfaceWithDefaultsMethods {

    void methode() {
        methodInherit();
        anotherMethod();
    }
}

আশা করি এটি আপনাকে সহায়তা করবে ...



2

এটা সম্ভব

public class ParallaxViewController<T extends View & Parallaxor> extends ParallaxController<T> implements AbsListView.OnScrollListener {

//blah
}

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

1

জাভা নির্মাতারা সিদ্ধান্ত নিয়েছিলেন যে একাধিক উত্তরাধিকারের সমস্যাগুলি সুবিধার চেয়ে বেশি, তাই তারা একাধিক উত্তরাধিকার অন্তর্ভুক্ত করেনি। আপনি একাধিক উত্তরাধিকারের বৃহত্তম সমস্যা (ডাবল হীরা সমস্যা) সম্পর্কে এখানে পড়তে পারেন

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


0

আপনি জাভা একাধিক উত্তরাধিকার করতে পারবেন না। ইন্টারফেস ব্যবহার বিবেচনা করুন:

interface I1 {}
interface I2 {}
class C implements I1, I2 {}

বা অভ্যন্তরীণ শ্রেণী:

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