Java Multiple Inheritance

前端 未结 17 1287
猫巷女王i
猫巷女王i 2020-11-22 09:36

In an attempt to fully understand how to solve Java\'s multiple inheritance problems I have a classic question that I need clarified.

Lets say I have class Ani

相关标签:
17条回答
  • 2020-11-22 10:24

    Interfaces don't simulate multiple inheritance. Java creators considered multiple inheritance wrong, so there is no such thing in Java.

    If you want to combine the functionality of two classes into one - use object composition. I.e.

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

    And if you want to expose certain methods, define them and let them delegate the call to the corresponding controller.

    Here interfaces may come handy - if Component1 implements interface Interface1 and Component2 implements Interface2, you can define

    class Main implements Interface1, Interface2
    

    So that you can use objects interchangeably where the context allows it.

    So in my point of view, you can't get into diamond problem.

    0 讨论(0)
  • 2020-11-22 10:25

    May I suggest the concept of Duck-typing?

    Most likely you would tend to make the Pegasus extend a Bird and a Horse interface but duck typing actually suggests that you should rather inherit behaviour. As already stated in the comments, a pegasus is not a bird but it can fly. So your Pegasus should rather inherit a Flyable-interface and lets say a Gallopable-interface.

    This kind of concept is utilized in the Strategy Pattern. The given example actually shows you how a duck inherits the FlyBehaviour and QuackBehaviour and still there can be ducks, e.g. the RubberDuck, which can't fly. They could have also made the Duck extend a Bird-class but then they would have given up some flexibility, because every Duck would be able to fly, even the poor RubberDuck.

    0 讨论(0)
  • 2020-11-22 10:25

    Java does not have a Multiple inheritance problem, since it does not have multiple inheritance. This is by design, in order to solve the real multiple inheritance problem (The diamond problem).

    There are different strategies for mitigating the problem. The most immediately achievable one being the Composite object that Pavel suggests (essentially how C++ handles it). I don't know if multiple inheritence via C3 linearization (or similar) is on the cards for Java's future, but I doubt it.

    If your question is academic, then the correct solution is that Bird and Horse are more concrete, and it is false to assume that a Pegasus is simply a Bird and a Horse combined. It would be more correct to say that a Pegasus has certain intrinsic properties in common with Birds and Horses (that is they have maybe common ancestors). This can be sufficiently modeled as Moritz' answer points out.

    0 讨论(0)
  • 2020-11-22 10:25

    I think it depends very much on your needs, and how your animal classes are to be used in your code.

    If you want to be able to make use of methods and features of your Horse and Bird implementations inside your Pegasus class, then you could implement Pegasus as a composition of a Bird and a Horse:

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

    Another possibility is to use an Entity-Component-System approach instead of inheritance for defining your animals. Of course this means, that you will not have individual Java classes of the animals, but instead they are only defined by their components.

    Some pseudo code for an Entity-Component-System approach could look like this:

    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);
    }
    
    0 讨论(0)
  • 2020-11-22 10:30

    To solve the problem of mutiple inheritance in Java → interface is used

    J2EE (core JAVA) Notes By Mr. K.V.R Page 51

    Day - 27

    1. Interfaces are basically used to develop user defined data types.
    2. With respect to interfaces we can achieve the concept of multiple inheritances.
    3. With interfaces we can achieve the concept of polymorphism, dynamic binding and hence we can improve the performance of a JAVA program in turns of memory space and execution time.

    An interface is a construct which contains the collection of purely undefined methods or an interface is a collection of purely abstract methods.

    [...]

    Day - 28:

    Syntax-1 for reusing the features of interface(s) to class:

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

    In the above syntax clsname represents name of the class which is inheriting the features from ‘n’ number of interfaces. ‘Implements’ is a keyword which is used to inherit the features of interface(s) to a derived class.

    [...]

    Syntax-2 inheriting ‘n’ number of interfaces to another interface:

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

    [...]

    Syntax-3:

    [abstract] class <derived class name> extends <base class name> implements <intf 1>,<intf 2>.........<intf n>
    {
      variable declaration;
      method definition or declaration;
    };
    
    0 讨论(0)
  • 2020-11-22 10:31

    As you will already be aware, multiple inheritance of classes in Java is not possible, but it's possible with interfaces. You may also want to consider using the composition design pattern.

    I wrote a very comprehensive article on composition a few years ago...

    https://codereview.stackexchange.com/questions/14542/multiple-inheritance-and-composition-with-java-and-c-updated

    0 讨论(0)
提交回复
热议问题