1 2 3 Previous Next 35 Replies Latest reply on Jan 5, 2005 10:01 AM by jwenting Go to original post
      • 15. Re: Multiple Inheritance
        807596
        Sorry I missed that you use that.
        • 16. Re: Multiple Inheritance
          807596
          Yeah, the problem is I can only extend one class.. not both
          • 17. Re: Multiple Inheritance
            807596
            Some recommendations:

            Bruce Eckel, author of Thinking In Java, has this to say about composition vs. inheritance:

            When deciding between inheritance and composition, ask if you need to upcast to the base type. If not, prefer composition (member objects) to inheritance. This can eliminate the perceived need for multiple base types. If you inherit, users will think they are supposed to upcast.

            Choose composition first when creating new classes from existing classes. You should only used inheritance if it is required by your design. If you use inheritance where composition will work, your designs will become needlessly complicated.

            Bill Venners: Composition versus Inheritance

            Use inheritance (of implementation) only when the class satisfies the following criteria:
            1) "Is a special kind of," not "is a role played by a";
            2) Never needs to transmute to be an object in some other class;
            3) Extends rather than overrides or nullifies superclass;
            4) Does not subclass what is merely a utility class (useful functionality you'd like to reuse); and
            5) Within PD: expresses special kinds of roles, transactions, or things.

            -- from Java Design: Building Better Apps and Applets (2nd Edition), by Peter Coad and Mark Mayfield
            • 18. Re: Multiple Inheritance
              807596
              Yeah, the problem is I can only extend one class..
              not both
              Have you considered this 4 level extension structure:

              BaseObject
              v
              ExtendedObject
              v
              BaseOracleObject
              v
              ExtendedOracleObject
              • 19. Re: Multiple Inheritance
                807596
                In my scenario BaseOracleObject would not know about ExtendedObject
                It's like the fruit-> apple scenario.. If I want a banana later I can't have the
                extendedfruit extend apple

                ie.
                It would look like this:

                Fruit
                V
                Apple
                V
                ExtendedFruit
                V
                ExtendedApple

                Should be

                Fruit - ExtendedFruit
                |
                | > Apple- ExtendedApple
                |
                | > Banana - ExtendedBanana

                From the previous comment I do get around this by using composition but it results in a lot code clutter.
                Extended apple on instantiation will have an instance of ExtendedFruit
                Then ExtendedApple.a() will have to defer to an internal instance of ExtendedFruit.a(). etc...
                • 20. Re: Multiple Inheritance
                  807596
                  In my scenario BaseOracleObject would not know about
                  ExtendedObject
                  Does BaseObject and ExtendedObject both contain general methods not yet specialized to any specfic database?
                  • 21. Re: Multiple Inheritance
                    807596
                    Yes the base and extended object defines the structure of the object and the base methods that determine it's behaviour.. The DB models form the layer that manipulates the data from the base/extended objects and deal with their respective DB's.

                    You would start with a BaseObject and the ExtendedDB classes.

                    Then later the base could be extended to provide extra functionality, thus the ExtendedDB classes need to be extended as well.
                    • 22. Re: Multiple Inheritance
                      JosAH
                      Because of the "multiple inheritance" double diamond.

                      Let's say you have two concrete C++ classes named Cowboy and Artist, both with methods named draw().
                      If you have another class that extends both Cowboy and Artist, what happens when your class calls the
                      draw() method? Do you get a nice oil painting or a rustler dead in the street?
                      That's a nice example, but that's not diamond MI; it's just a collision of method names.
                      A diamond would be an 'Appliance' class, with two sub-classes, 'AlarmClock' and 'Radio'.
                      A third class, the 'AlarmClockRadio', needs to have one sub-object, i.e. one 'Appliance'
                      instead of two ...
                      That one 'Appliance' would/could take care of the 'getSerialNumber()' functionality ...

                      But you're right, a method name collision is just as bad a design.

                      kind regards,

                      Jos
                      • 23. Re: Multiple Inheritance
                        807596
                        That's a nice example, but that's not diamond MI;
                        it's just a collision of method names.
                        A diamond would be an 'Appliance' class, with two
                        sub-classes, 'AlarmClock' and 'Radio'.
                        A third class, the 'AlarmClockRadio', needs to have
                        one sub-object, i.e. one 'Appliance'
                        instead of two ...
                        That one 'Appliance' would/could take care of the
                        'getSerialNumber()' functionality ...
                        I don't see why this would cause a problem unless there were two implementations of on method which boils down to the same problem described by the Cowboy - Artist example.

                        I do have a big problem with the Cowboy - Artist example, though: one doesn't draw an oil painting.
                        • 24. Re: Multiple Inheritance
                          807596
                          Interfaces and the 'diamond problem'

                          One justification of interfaces that I had heard early on was that they solved the "diamond problem" of traditional multiple inheritance. The diamond problem is an ambiguity that can occur when a class multiply inherits from two classes that both descend from a common superclass. For example, in Michael Crichton's novel Jurassic Park, scientists combine dinosaur DNA with DNA from modern frogs to get an animal that resembled a dinosaur but in some ways acted like a frog. At the end of the novel, the heros of the story stumble on dinosaur eggs. The dinosaurs, which were all created female to prevent fraternization in the wild, were reproducing. Chrichton attributed this miracle of love to the snippets of frog DNA the scientists had used to fill in missing pieces of the dinosaur DNA. In frog populations dominated by one sex, Chrichton says, some frogs of the dominant sex may spontaneously change their sex. (Although this seems like a good thing for the survival of the frog species, it must be terribly confusing for the individual frogs involved.) The dinosaurs in Jurassic Park had inadvertently inherited this spontaneous sex-change behavior from their frog ancestry, with tragic consequences.

                          This Jurassic Park scenario potentially could be represented by the following inheritance hierarchy:
                                    Animal
                                    /    \
                                 Frog   Dinosaur
                                    \    /
                                   Frogasaur
                          The diamond problem can arise in inheritance hierarchies like the one shown in Figure 1. In fact, the diamond problem gets its name from the diamond shape of such an inheritance hierarchy. One way the diamond problem can arise in the Jurassic Park hierarchy is if both Dinosaur and Frog, but not Frogosaur, override a method declared in Animal. Here's what the code might look like if Java supported traditional multiple inheritance:
                          abstract class Animal {
                          
                              abstract void talk();
                          }
                          
                          class Frog extends Animal {
                          
                              void talk() {
                          
                                  System.out.println("Ribit, ribit.");
                          }
                          
                          class Dinosaur extends Animal {
                          
                              void talk() {
                                  System.out.println("Oh I'm a dinosaur and I'm OK...");
                              }
                          }
                          
                          // (This won't compile, of course, because Java
                          // only supports single inheritance.)
                          class Frogosaur extends Frog, Dinosaur {
                          }
                          The diamond problem rears its ugly head when someone tries to invoke talk() on a Frogosaur object from an Animal reference, as in:
                          Animal animal = new Frogosaur();
                          animal.talk();
                          Because of the ambiguity caused by the diamond problem, it isn't clear whether the runtime system should invoke Frog's or Dinosaur's implementation of talk(). Will a Frogosaur croak "Ribbit, Ribbit." or sing "Oh, I'm a dinosaur and I'm okay..."?

                          The diamond problem would also arise if Animal had declared a public instance variable, which Frogosaur would then have inherited from both Dinosaur and Frog. When referring to this variable in a Frogosaur object, which copy of the variable -- Frog's or Dinosaur's -- would be selected? Or, perhaps, would there be only one copy of the variable in a Frogosaur object?

                          In Java, interfaces solve all these ambiguities caused by the diamond problem. Through interfaces, Java allows multiple inheritance of interface but not of implementation. Implementation, which includes instance variables and method implementations, is always singly inherited. As a result, confusion will never arise in Java over which inherited instance variable or method implementation to use.
                          • 25. Re: Multiple Inheritance
                            JosAH
                            I don't see why this would cause a problem unless
                            there were two implementations of on method which
                            boils down to the same problem described by the
                            Cowboy - Artist example.
                            It's not so much the colliding method names as well as having two sub-objects
                            in the derived class object, i.e. does an AlarmClockRadio have two sub-objects
                            as its data, i.e. one from the AlarmClock and one inherited from the Radio class,
                            both being appliances? IOW, an Appliance take |A| Bytes of storage, an AlarmClock
                            takes |A|+|C| bytes of storage and a Radio takes |A|+|R| bytes of storage; should
                            an AlarmClockRadio take up 2*|A|+|C|+|R| bytes of storage or just |A|+|C|+|R| bytes?
                            That's what that diamond is all about ...
                            I do have a big problem with the Cowboy - Artist
                            example, though: one doesn't draw an oil painting.
                            Indeed, you paint it instead ;-)

                            kind regards,

                            Jos
                            • 26. Re: Multiple Inheritance
                              807596
                              It's not so much the colliding method names as well
                              as having two sub-objects
                              in the derived class object, i.e. does an
                              AlarmClockRadio have two sub-objects
                              as its data, i.e. one from the AlarmClock and one
                              inherited from the Radio class,
                              both being appliances? IOW, an Appliance take |A|
                              Bytes of storage, an AlarmClock
                              takes |A|+|C| bytes of storage and a Radio takes
                              |A|+|R| bytes of storage; should
                              an AlarmClockRadio take up 2*|A|+|C|+|R| bytes of
                              storage or just |A|+|C|+|R| bytes?
                              That's what that diamond is all about ...
                              I think that can be easily resolved by the compiler. There would only be one Appliance data section for each AlarmClockRadio since there is only one Object.

                              However I now see why this is different from the simple name collsion. If the Radio constructor sets the value of an Appliance member to one thing and the AlarmClock sets it to another, who wins?

                              Simple name collisions could be resolved to some degree by the type of the reference used (though I don't know what you do when the reference type is a CowboyArtist) but that is not true if the base class is the same.

                              Since all Objects extend Object in Java, the diamond problem would come up all the time in Java. which toString()? Which equals()/hashCode()?
                              • 27. Re: Multiple Inheritance
                                JosAH
                                I think that can be easily resolved by the compiler.
                                There would only be one Appliance data section for
                                r each AlarmClockRadio since there is only one
                                Object.
                                Sure, the C++ language deals with 'private' as well as 'virtual' inheritance, effectively
                                dealing (or determining) with that diamond inheritance. MI is no magic, it's just
                                confusing ... ;-)
                                However I now see why this is different from the
                                simple name collsion. If the Radio constructor sets
                                the value of an Appliance member to one thing and the
                                AlarmClock sets it to another, who wins?
                                See? I told you so ;-)
                                Simple name collisions could be resolved to some
                                degree by the type of the reference used (though I
                                don't know what you do when the reference type is a
                                CowboyArtist) but that is not true if the base class
                                is the same.
                                Yep, C++ handles that in a very subliminal way, i.e. writing class D: B, A
                                means something completely different as class D: A, B, i.e. order is
                                significant here ...
                                Since all Objects extend Object in Java, the diamond
                                problem would come up all the time in Java. which
                                toString()? Which equals()/hashCode()?
                                Yep, Java simply annihilates the problem by not offering the nasty (but powerful)
                                MI of implementation ... it doesn't deal with name collisions from different
                                interfaces though, which I find a bit ugly. (all IMHO that is).

                                kind regards,

                                Jos
                                • 28. Re: Multiple Inheritance
                                  807596
                                  Yes the base and extended object defines the
                                  structure of the object and the base methods that
                                  determine it's behaviour..
                                  Well my point is that if BaseObject and ExtendedObject are both general they basically could be treated as one superclass. That's maybe not nice but it would work.

                                  In a case like this I think the Bridge pattern can be used to get rid of the multiple inheritance situation. Maybe in combination with Visitor.
                                  • 29. Re: Multiple Inheritance
                                    807596
                                    Yep, Java simply annihilates the problem by not
                                    offering the nasty (but powerful)
                                    MI of implementation ... it doesn't deal with name
                                    collisions from different
                                    interfaces though, which I find a bit ugly. (all IMHO
                                    that is).
                                    I've never really run into this though. I think it only really comes up frequently (if that) when developers think that they have to have a single class that implements a billion different interfaces. Usually I find it more clean to use inner classes (etc.) to implement non-primary interfaces.