Multiple Inheritance in different Programming Languages

Accname

2D-Graphics enthusiast
Reaction score
1,462
Hi there.

I am curious as to what would be the best way of implementing multiple inheritance in programming languages.
I have made some thoughts about this topic and came up with the following solution.
I would like to know what you guys think about it, what the problems would be with this and how it is done in different languages.

Heres an example of what I have in mind:
Code:
public class Artist {
   
    public void draw() {
        System.out.println("A nice sketch is being drawn.");
    }
   
}
 
public class Cowboy {
   
    public void draw() {
        System.out.println("A bullet is fired.");
    }
   
}
 
// This class inherits the methods of both Cowboys and Artists
public class ArtisticCowboy extends Cowboy, Artist {
 
   // This method will be called when a method expects an Cowboy but gets an ArtisticCowboy
    public void (Cowboy) draw() {
        super(Cowboy).draw();
    }
 
   // This method will be called when a method expects an Artist but gets an ArtisticCowboy
    public void (Artist) draw() {
        super(Artist).draw();
    }
   
}
 
public class Competition {
   
    public static void main(String[] args) {
        ArtistCowboy ac = new ArtistCowboy();
        addCowboyContestant(ac); // Out: "A bullet is fired."
        addArtistContestant(ac); // Out: "A nice sketch is being drawn."
    }
   
    public void addCowboyContestant(Cowboy cowboy) {
        cowboy.draw();
    }
   
    public void addArtistContestant(Artist artist) {
        artist.draw();
    }
   
}
 

monoVertex

I'm back!
Reaction score
460
In Python classes inherit attributes on a depth-first, left-to-right order. That is, if they don't override said attributes.

However, I fail to see why polymorphism is not acceptable to you, regarding the parent-specific method (public void (Artist) draw(), for example). If you want the object to act as an Artist, polymorphism should come into play and when you cast the object as an Artist and call draw, the draw method on the Artist super class should be called automatically. Same goes for Cowboy. Now, if the CowboyArtist has its own draw method, that is called when you're having a CowboyArtist-casted object. If it does not, find a method to choose from one of the parents' methods.

Your solution adds programming overhead and also breaks polymorphism, which means it's not OOP anymore. What happens if I don't specify a super-class specific method? I can't call that method on the super class at all?

This means I'd rather see it like this:

Code:
public class Artist {
    public void draw() {
        System.out.println("A nice sketch is being drawn.");
    }
}
 
public class Cowboy {
    public void draw() {
        System.out.println("A bullet is fired.");
    }
}
 
// This class inherits the methods of both Cowboys and Artists
public class ArtisticCowboy extends Cowboy, Artist {
 
    public void draw() {
        System.out.println("A nice sketch of a bullet is being drawn.");
    }
 
}
 
public class Competition {
 
    public static void main(String[] args) {
        ArtistCowboy ac = new ArtistCowboy();
        addCowboyContestant(ac); // Out: "A bullet is fired."
        addArtistContestant(ac); // Out: "A nice sketch is being drawn."
        ac.draw() // Out: "A nice sketch of a bullet is being drawn."
    }
 
    public void addCowboyContestant(Cowboy cowboy) {
        cowboy.draw();
    }
 
    public void addArtistContestant(Artist artist) {
        artist.draw();
    }
 
}

Now, leaving aside the parent-specific methods, the super method calling you have (super(Artist).draw()) is implemented quite similar in Python as well. The downside is that you have to do that when having a single Parent as well, which is really ugly, especially if you change the parent for a class with the same interface, later. That's a maintenance nightmare, and I am not sure why couldn't you infer the parent automatically, when having a single one. /rant

So you could do this:

Code:
public class Artist {
    public void draw() {
        System.out.println("A nice sketch is being drawn.");
    }
}
 
public class Cowboy {
    public void draw() {
        System.out.println("A bullet is fired.");
    }
}
 
// This class inherits the methods of both Cowboys and Artists
public class ArtisticCowboy extends Cowboy, Artist {
 
    public void draw() {
        super(Artist).draw();
        super(Cowboy).draw();
    }
 
}
 
public class Competition {
 
    public static void main(String[] args) {
        ArtistCowboy ac = new ArtistCowboy();
        addCowboyContestant(ac); // Out: "A bullet is fired."
        addArtistContestant(ac); // Out: "A nice sketch is being drawn."
        ac.draw() /// Out: "A bullet is fired. A nice sketch is being drawn."
    }
 
    public void addCowboyContestant(Cowboy cowboy) {
        cowboy.draw();
    }
 
    public void addArtistContestant(Artist artist) {
        artist.draw();
    }
 
}
 

Accname

2D-Graphics enthusiast
Reaction score
1,462
I think I didnt do the example quite right. That was not exactly what I had in mind.
I was thinking more along this line:

There are various different ways of doing it:
Code:
public class ArtisticCowboy extends Cowboy, Artist {
 
    public void (Cowboy) draw() {
        super(Cowboy).draw();
    }
 
    public void (Artist) draw() {
        super(Artist).draw();
    }
 
}
 
public class Competition {
 
    public static void main(String[] args) {
        ArtistCowboy ac = new ArtistCowboy();
        addCowboyContestant(ac); // Out: "A bullet is fired."
        addArtistContestant(ac); // Out: "A nice sketch is being drawn."
    }
 
}
Code:
public class ArtisticCowboy extends Cowboy, Artist {
 
    public void draw() {
        print("A very nice bullet is being drawn.");
    }
 
}
 
public class Competition {
 
    public static void main(String[] args) {
        ArtistCowboy ac = new ArtistCowboy();
        addCowboyContestant(ac); // Out: "A very nice bullet is being drawn."
        addArtistContestant(ac); // Out: "A very nice bullet is being drawn."
    }
 
}
Code:
public class ArtisticCowboy extends Cowboy, Artist {
 
    public void (Cowboy) draw() {
        super(Cowboy).draw();
    }
 
    public void (Artist) draw() {
        super(Artist).draw();
    }
 
    public void draw() {
        print("A very nice bullet is being drawn.");
    }
 
}
 
public class Competition {
 
    public static void main(String[] args) {
        ArtistCowboy ac = new ArtistCowboy();
        addCowboyContestant(ac); // Out: "A bullet is fired."
        addArtistContestant(ac); // Out: "A nice sketch is being drawn."
        ac.draw(); // Out: "A very nice bullet is being drawn."
    }
 
}
Code:
public class ArtisticCowboy extends Cowboy, Artist {
 
}
 
public class Competition {
 
    public static void main(String[] args) {
        ArtistCowboy ac = new ArtistCowboy();
        addCowboyContestant(ac); // Out: "A bullet is fired."
        addArtistContestant(ac); // Out: "A nice sketch is being drawn."
        ac.draw(); // Error: There is no "draw()" method for ArtistCowboy class
    }
 
}
 

monoVertex

I'm back!
Reaction score
460
Well, this still breaks inheritance. If I don't inherit methods automatically unless I add some code in my class, what is the point of inheritance then, as it's almost the same as aggregation.
 

monoVertex

I'm back!
Reaction score
460
In your last example, calling ac.draw() fails. That means that the child class does not inherit anything when there's a conflict, which is not good, in my opinion. That's why Python, for example, has a rule which determines which one of the classes provides the method to be inherited when there is a conflict.

The CowboyArtist is a child of both Cowboy and Artist, so he should inherit a draw method, that's how inheritance works. With your method, you have to explicitly define a method, and that's no longer inheritance.
 

Accname

2D-Graphics enthusiast
Reaction score
1,462
But I dont think that is a good mechanic, its elusive. It shouldnt matter in which order you write the classes, the result should be the same.
In the last example there is a conflict between the super classes, and as long as you, as a programmer, dont resolve the conflict, the compiler wont do it for you.

Of course, if the ArtisticCowboy would only expand either Cowboy or Artist, then you could call draw() on the ArtisticCowboy.
 

monoVertex

I'm back!
Reaction score
460
Why not provide a mechanism to specify the default class from which to inherit everything, when you have multiple inheritance, if you don't want to rely on order of writing?

What bothers me is that if I want to extend 2 classes that have the same 10 methods, each one of them has extra 5 methods that do not conflict and I also want those initial 10 to be inherited from the first class, let's say, then I have to redefine all those first 10 methods in the new class, as some simple wrappers for the super functions, which would result in bloated code.

Here's what I am thinking of:

Code:
public class ArtisticCowboy extends Cowboy, Artist {
     inherits(Cowboy);
}
 
public class Competition {
 
    public static void main(String[] args) {
        ArtistCowboy ac = new ArtistCowboy();
        addCowboyContestant(ac); // Out: "A bullet is fired."
        addArtistContestant(ac); // Out: "A nice sketch is being drawn."
        ac.draw(); // Out: "A bullet is fired."
    }
 
}

Or, if the user wants 2 of the original 10 from one class and the other 8 methods from the second class, don't force him, again, to write wrappers. Why not introduce a new keyword, let's say "inherits" with which you can specify which methods to inherit from which class, instead of writing one-line wrappers.

Like this:

Code:
public class ArtisticCowboy extends Cowboy, Artist {
     inherits(Cowboy) draw;
     inherits(Artist) draw;
 
    public void draw() {
        print("A very nice bullet is being drawn.");
    }
 
}
 
public class Competition {
 
    public static void main(String[] args) {
        ArtistCowboy ac = new ArtistCowboy();
        addCowboyContestant(ac); // Out: "A bullet is fired."
        addArtistContestant(ac); // Out: "A nice sketch is being drawn."
        ac.draw(); // Out: "A very nice bullet is being drawn."
    }
 
}

Of course, this is really ugly, I haven't given too much thought to the actual syntax, but it saves lines and makes the code far more readable.

I have the same grudge with basic setters and getters, why can't a language have a construct through which you can define this as meta information and it generates it for you automatically. Of course, if you want to do something fancy in your setter or getter then use the old way.
 

Accname

2D-Graphics enthusiast
Reaction score
1,462
Well, that could work.
It would be a construct to make it easier on the developers I guess. But I really dont like to introduce more syntax. You know, in my opinion the language should be made as simple as possible but giving a lot of freedom and flexibility.

But that one keyword to dissolve conflicts would be handy I guess.

Have you ever thought about a less OOP approach? Instead of extending classes you could "include" methods from other classes?
Something like this:
Code:
public class ArtisticCowboy {
 
    include (Cowboy.*);
    include (Artist.*);

    public void draw() {
          print("...");      
    }
}
Could be funny I guess. But I dont quite know how you would deal with the variables.

Most java IDE's can generate getter and setters for you and hide them (effectively making them a single line).
 

monoVertex

I'm back!
Reaction score
460
Well, that could work.
It would be a construct to make it easier on the developers I guess. But I really dont like to introduce more syntax. You know, in my opinion the language should be made as simple as possible but giving a lot of freedom and flexibility.

But that one keyword to dissolve conflicts would be handy I guess.

Well, the developer can just not use the keyword I suggested, if they wish, and use your initial syntax. I see no conflict between your initial implementation and what I suggested and it would just represent syntactic sugar.

Have you ever thought about a less OOP approach? Instead of extending classes you could "include" methods from other classes?
Something like this:
Code:
public class ArtisticCowboy {
 
    include (Cowboy.*);
    include (Artist.*);
 
    public void draw() {
          print("...");
    }
}
Could be funny I guess. But I dont quite know how you would deal with the variables.

I assumed you were aiming for an OOP solution, hence my reasoning.

However, not sure how I feel about the inclusion thing. I quite like it, but on the other hand, are you still having polymorphism for the classes? If yes, I don't think that considering every class you include from as a parent is a good solution and might be hard to implement.

If you're dropping polymorphism, then I don't see any issue with this construct at the moment. I have to think about it some more :D.

Most java IDE's can generate getter and setters for you and hide them (effectively making them a single line).

Yes, but that's an IDE function, whereas meta-programming would be a more consistent approach to this issue in particular. This way you ensure every developer has a similar experience, instead of relying on IDEs and IDE configurations.
 

Accname

2D-Graphics enthusiast
Reaction score
1,462
Well, you can always declare your variables public if you just want simple get and set methods. But of course, some people dont like to have public variables. (Me, for example)
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top