Extending from two classes
Asked Answered
P

13

206

How can I do this:

public class Main extends ListActivity , ControlMenu 

Also, I would like to know that is this approach is okay that I have made the menus in class which is ControlMenu and I am extending in rest of the activities.

Prepositor answered 29/4, 2011 at 19:45 Comment(1)
You can't extend two or more classes at one time. Multiple inheritance is not allowed in java.Gelation
A
199

You can only Extend a single class. And implement Interfaces from many sources.

Extending multiple classes is not available. The only solution I can think of is not inheriting either class but instead having an internal variable of each class and doing more of a proxy by redirecting the requests to your object to the object that you want them to go to.

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

this is the best solution I have come up with. You can get the functionality from both classes and Still only actually be of one class type.

The drawback is that you cannot fit into the Mold of the Internal class using a cast.

Appeasement answered 29/4, 2011 at 19:54 Comment(4)
you were quicker :) I'll leave my answer as some abstract rambling to compare to your concrete example ;)Flor
This is a very nice alternative, and provides a lot more flexibility in the future.Boak
See @SCB solution for more a more OOP solutionTruax
I could use a more precise example here. Not sure I understand.Gar
I
76

As everyone else has said. No, you can't. However even though people have said many times over the years that you should use multiple interfaces they haven't really gone into how. Hopefully this will help.

Say you have class Foo and class Bar that you both want to try extending into a class FooBar. Of course, as you said, you can't do:

public class FooBar extends Foo, Bar

People have gone into the reasons for this to some extent already. Instead, write interfaces for both Foo and Bar covering all of their public methods. E.g.

public interface FooInterface {

    public void methodA();

    public int methodB();

    //...
} 

public interface BarInterface {

    public int methodC(int i);

    //...
}

And now make Foo and Bar implement the relative interfaces:

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

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

Now, with class FooBar, you can implement both FooInterface and BarInterface while keeping a Foo and Bar object and just passing the methods straight through:

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

    //...

}

The bonus for this method, is that the FooBar object fits the moulds of both FooInterface and BarInterface. That means this is perfectly fine:

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

Hope this clarifies how to use interfaces instead of multiple extensions. Even if I am a few years late.

Imbricate answered 1/6, 2015 at 13:1 Comment(5)
this is the best answerContinuity
This is a very good answer, however I see a couple issues with it that would need to be addressed in more detail. First extending from two existing classes would be a bit more problematic and there would be a number of extra hurdles to go through, Second is if interface Foo and Bar both had the same functions, you would need to have an order of precedence. Explicitly extending your class would force you to make those decisions up front. Still, Excellent option :) +1Appeasement
What if we have to create new classes "frequently" and make each of those classes implement both the interfaces ? Then, we'd have to repeat these boilerplate implementations in each class. Is there a better way to make a class "implement" two sets of behaviors ?Hiroshige
@MasterJoe2 To be honest, I haven't done very much using Java for a while now (I stopped around the time I wrote this answer). One of the reasons I avoid it now-a-days is the very issue you raise. A hunch for a direction you could possibly investigate, is writing an abstract class that implements both interfaces, and extend that. However I have no clue if that's valid Java, and I feel that you'll just end up with the same original problem when you want to make changes to the implementing class in the future. Sorry I can't be more of a help.Imbricate
Mostly, I like this approach EXCEPT that it ignores the whole idea of protected methods which is why you definitely want and need to have a child class based on multiple parent classes. Now we have private interface methods which are a really bad solution to an otherwise elegant (and straightforward) multi-class inheritance problem. Real World: Camino is a Car and a Truck -- motortrend.com/features/coolest-car-trucks-crucks-utes-all-timeHoekstra
T
57

Why Not Use an Inner Class (Nesting)

class A extends B {
    private class C extends D {
        //Classes A , B , C , D accessible here 
    }
}
Tanto answered 5/12, 2012 at 4:15 Comment(4)
Intersting approach, what do experts think of this technique? I'd like to dig into it.Toga
Is it OK with conventions?Discontent
Could not get inner class to work in a Fragment. My activity must extend Fragment, which means I absolutely need getView(), which won't work if it's inside the inner class, and the code in there is where I need to use code from ListActivity, so I can't extend twice, OR do an inner class in this example.Hagerman
This is the best solution for extending abstract classes where you need access to variables of the impementing class.Narbonne
B
39

You will want to use interfaces. Generally, multiple inheritance is bad because of the Diamond Problem:

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

C++ and others have a couple ways to solve this, eg

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

but Java only uses interfaces.

The Java Trails have a great introduction on interfaces: http://download.oracle.com/javase/tutorial/java/concepts/interface.html You'll probably want to follow that before diving into the nuances in the Android API.

Boak answered 29/4, 2011 at 19:52 Comment(6)
I never understood why the diamond problem is actually a problem that prevents multiple inheritance. Why can't the compiler just complain if there are conflicting methods with the same name?Leatherman
For sufficiently intelligent compilers, it's not. Solving it at the compiler level is possible, and indeed C++ does it with virtual class. Doing so comes with many warnings and caveats, both for the compiler and the developer.Boak
How about the same default methods in two interfaces? That is another example of the diamond problem, which java can handle.Counterblast
@MészárosLajos But you do not call super from in a method inheriting. Well, you can, but you have to specify the interface method to invoke(and it must use the keyword default in the interface implementation). An example is: MyIFace.super.foo() where MyIFace is an interface. As you can see the interface method to execute is defined and avoids the Diamond Problem entirely. If you extend MyClass1 and MyClass2, both classes have a foo(), and call super.foo() then the compiler is thrown by the Diamond Problem.Triturable
You cannot return "bar" or "baz" with method type of void. Anyways, good explanation xDKeaton
Huh. 5 years later and I never noticed those should obviously be string. Will fix that asap.Boak
F
22

Yea, as everyone else wrote, you cannot do multiple inheritance in Java. If you have two classes from which you'd like to use code, you'd typically just subclass one (say class A). For class B, you abstract the important methods of it to an interface BInterface (ugly name, but you get the idea), then say Main extends A implements BInterface. Inside, you can instantiate an object of class B and implement all methods of BInterface by calling the corresponding functions of B.

This changes the "is-a" relationship to a "has-a" relationship as your Main now is an A, but has a B. Depending on your use case, you might even make that change explicit by removing the BInterface from your A class and instead provide a method to access your B object directly.

Flor answered 29/4, 2011 at 19:56 Comment(1)
This is the most legible and easy to understand explanation. More upvotes please.Schadenfreude
M
14

Make an interface. Java doesn't have multiple inheritance.

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

Mediator answered 29/4, 2011 at 19:46 Comment(3)
aww why the downvote? I wasn't being mean, I just think he could afford to do some reading and think about the problem on his own first before we construct his classes for himMediator
I suspect there are patterns that benefit from multiple inheritance of behavior. Don't deny me a technique just because others have made mistakes with itArgenteuil
This is not always a good solution as interfaces cannot contain non-final member variables.Swope
T
6

Java does not support multiple inheritance, but you can try to implement two or more interface.

Tacklind answered 29/4, 2011 at 20:50 Comment(0)
J
6

Like another alternative, maybe you can use an interface with a default implementation of a method. That depends of course of what you want to do.

For example, you can create an abstract class and an interface:

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

So, after that, you can extend and implements both classes and use both methods.

public class extends FatherClass implements InterfaceWithDefaultsMethods {

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

Hope this helps you...

Jasun answered 28/9, 2017 at 20:36 Comment(0)
P
4

Yes. slandau is right. Java does not allow extending from several classes.

What you want is probably public class Main extends ListActivity implements ControlMenu. I am guessing you are trying to make a list.

Hope that helps.

Placard answered 29/4, 2011 at 19:50 Comment(0)
I
2

Extending from multiple classes is not allowed in java.. to prevent Deadly Diamond of death !

Isotonic answered 13/1, 2014 at 18:17 Comment(0)
F
2

The creators of java decided that the problems of multiple inheritance outweigh the benefits, so they did not include multiple inheritance. You can read about one of the largest issues of multiple inheritance (the double diamond problem) here.

The two most similar concepts are interface implementation and including objects of other classes as members of the current class. Using default methods in interfaces is almost exactly the same as multiple inheritance, however it is considered bad practice to use an interface with only default methods.

Feudalize answered 24/10, 2018 at 0:2 Comment(0)
H
1

it is possible

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

//blah
}
Hekker answered 25/6, 2014 at 10:35 Comment(1)
Parallaxor and ParallaxController are unknown, so I assume they aren't SDK-classes. So this doesn't work for me(and thus this answer shows errors). What is ParallaxController? Is this a specific dependency? Please elaborateThermotherapy
A
1

you can't do multiple inheritance in java. consider using interfaces:

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

or inner classes:

class Outer {
    class Inner1 extends Class1 {}
    class Inner2 extends Class2 {}
}
Avocado answered 4/11, 2018 at 2:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.