I really appreciate the way you take high level concepts and present them in a digestible manner. I would love to hear you talk about design patters in Java. I feel it's a topic that is somewhat ambiguous and I feel that your high level analysis of it would greatly help me and many others!
Spicy comment incoming: So, I can tell that this is a beginner friendly channel, but it would've been nice to at least mention in passing that inheritance is a bad practice ("Composition over Inheritance"). Here's a few resources that have great coverage of this concept: - I greatly appreciate that you've included "Effective Java" in the video description, which is a beautifully written book -- it actually covers this concept as Item 18, which is titled... "Composition over Inheritance". - I'd imagine that you're also familiar with the "Design Patterns" book by "the gang of four" (another very classic book in the industry) which also covers the concept of "Composition over Inheritance" in the very first chapter (p. 18 of my copy of the book). - Some languages such as Golang (the language that Google created for their own software engineers) go as far as to not even implement inheritance within the language. The alternative to solution to inheritance would be "delegation", which is composition + forwarding. This is a rather clunky pattern in vanilla approaches to Java, but I saw that you thankfully have a video on Lombok, which has the "@Delegate" syntax sugar as an experimental feature. I see you have some other videos that have already covered a lot of very awesome topics in a concise and beginner-friendly way, like Generics, Reflection ("meta-programming"), Lombok, Records (building block of algebraic data types), Checked vs Unchecked exceptions. The only unturned stone that I can actually think of is "Data vs Object", which Robert Martin covered in a great blog post over here: blog.cleancoder.com/uncle-bob/2019/06/16/ObjectsAndDataStructures.html
while I generally favor composition over inheritance, it's far from considered "bad practice" and is often the best way forward for extending pre-existing functionality. I feel like claiming that inheritance is bad practice is somewhat in-vogue. Granted it can (and often does) get messy, and so you *do* need to be careful with how you abstract things or else you definitely end up with a monster that can be difficult to tame. That being said, opportunities for Composition where it is not overly redundant should generally be preferred
John, you the definition of what makes a good teacher. You have passion, knowledge, and dedication. Teaching isn't a skill. It's simply someone who understands something so well that they can break it down to it's simplest form and explain it in a way without trying to show off. You just that, every teacher should learn from you!
I definitely thought about it! Basically how it works is, as long as the interfaces don't both have default implementations, there's no real conflict to resolve. The class can still implement that method that both interfaces specify. If they do both have default implementations, and you don't specify your own, it's simply a compilation error.
If the diamond problem is the reason for not having multiple inheritance, then why can you implement multiple interfaces that could have the same default method implementation? In my opinion, It would be neater if the subclass would treat a superclass method implementation conflict as an abstract method, so that you'd have to be explicit about which implementation you'd want (or if you wanted a whole different implementation). Only if the method was final it should give an exception.
This problem somewhat returned the moment when interfaces got default implementations in Java 8. So in some cases a developer is forced to choose which interface default implementation he wants to use, but it's compiler enforced and quite rare in practice. As for a diamond issue the bigger problem in my opinion are fields rather than methods. In case of methods you can choose an implementation as mentioned before, but in case of fields you can't just "pick" which field version you want to use safely without potentially messing up something.
I find the diamond problem argument a bit of a meme because of the existence of default interface methods since Java 8. By that I mean it already exists in the language and you have tools to resolve that conflict while preserving the multi inheritance of interfaces. The more likely reason I can think of is performance - with single inheritance, class fields always have the same offset within the memory of an object and type casting becomes basically free.
I have actually tried to implement annotation interfaces in a class before and I was surprised when I saw you do it too. And yes I made a class that implements Deprecated, and realized that the required methods are actually the annotation members, as well as the annotationType() method. And while testing this, I found out that annotation interfaces without any members are actually functional interfaces, and giving them the @FunctionalInterface annotation works.
I Really like the way you explain coding stuff, even things I already know I watch the video patiently and learn something new. The way you speak english is nice even for foreign like me. Thanks again John ! See you next time!
It has been clear for me that multiple inheritance is not necessary since I started programming in rust. There is no inheritance at all in that language. There are interfaces in rust however.
rust did it well. inheritance is unnecessary and encourages you to over-engineer your code. traits in rust are fantastic because you get exactly as much abstraction as you need without going overboard
Overall excellent video, citing Gosling and stressing the "philosophy of simplicity" of Java is spot on, but I think one should make the distinction that using interfaces only gives you the same advantages as multiple inheritance as far as polymorphism is concerned, but NOT as far as code reuse is concerned, and inheritance is at its core a code reuse technique. But then again, there are other ways to achieve code reuse, like composition, so refusing multiple inheritance makes sense if you are after a language that maximise simplicity and not flexibility and power.
8:00 Well here's the sitch: Cat is an abstract class written by someone else that you aren't allowed to change. Dog is from a licensed library package which you don't have the source code for. Your manager is telling you to implement Cog in 5 minutes since "everything's been done already".
8:06 I've had a couple instances where I've wished Java had multiple inheritance. It wasn't really the only solution, just the alternative was a messy approach that involved duplicating a lot of code.
We had this multiple times in our code base, although the problem mostly came up when some of the actual java base classes better should have been designed to be interfaces. Seems to be especially true in Java UI classes that did not change mostly due to compatibiltiy reasons...
I'm curious if you had specific examples. I think in most cases, we've been conditioned to prefer composition instead of inheritance and I think in most cases, the projects I've worked on rely less and less on inheritance for behavior and really just the properties/values.
@@th3runaway I think the use cases I had which this would would have helped with are both instances where I don't have control over what the parent classes are doing. From memory, (modding minecraft) one was adding functionality to both Villagers and Zombie Villagers. The other was using the same model for two entities but generic constraits prevent me from doing that, so I have to make a "Proxy" class for the second that wraps the model for the first.
There one case where the multiple inheritance is missing, it's when you want to inherit from a class that it's not yours and don't duplicate code. For exemple, if you have an interface that allow to get/set data from a database with a standardized solution (use of getType() to know table, then fetch provided attribut) and give those function to 2 objects, then you can either duplicate the whole code, or create a common abstract object. But what if you want to add this feature to object that can be create in database, like MyCat & MyDog, but you can't on the Animal, Cat & Dog because it's not your ? Before Java 1.7, it was not possible without code duplication. Since Java 1.8, you may try to provide default function on interface, but you still need a getType() which is not available in your interface. You can trick java by creating this method in the interface, because if the method exist in at least one of your parent, compilation work. The downside is that you need to declare an AnimaleLike interface to provide signature of all needed function to your own interface, so you still have a bit of a duplication.
I discovered your channel today, let me tell you, your content is incredible! I love how simplified yet informative your explanations are, it says alot about how well you know what you're doing, I love the jokes you implement here and there as well, the whole thing is very interesting and educational from start to finish, light hearted and well put together. perfect to my taste! 🎉
I've got one!! Please believe me :P I'm working on a graphing package in Java, and one of the superclasses (abstract) is Plot, from which inherit LinePlot and ScatterPlot (not abstract). I have been wanting to create a LineScatterPlot class, and have kept on thinking that this would have been a perfect time for multiple inheritance. But yes, I will find a way around it... :P
To me multiple inheritance is just another useful tool in the box that unfortunately is not available in Java. One appropriate use would be the implementation of modular classes that can then be combined into a whole range of different combinations. Coming from C++ I sometimes do miss that language feature. Of course one can emulate that behavior with Java constructs like helper classes and/or default implementations in interfaces (which again introduces the oh-so-terrible diamond problem that doesn't actually exist in Java.). At the end these workaraounds require me to spread code all over the place that IMO better should be kept together in a single class. Of course one can do all kinds of stupid things using multiple inheritance. As with almost any other advanced tool. Carpenters use nail guns. When used appropriately they increase productivity and allow to work faster and with more accuracy. Sure you can shoot yourself in the foot with a nail gun. That is why you never let the inexperienced apprentice use it unsupervised, you observe best practises and safety procedures and you always wear protective gear. Only the Java language designers would come to the conclusion that nail guns should be banned altogether.
Hey John! Would be really cool if you made an explanation video for Futures, it seems like a feature like Optionals where it seems to be somewhat overlooked. Thanks!
Python developer here: Its always baffled me that people actually use multiple inheritance. Not only have I seen it in in multiple stack overflow answers and tutorials, but actually in production. Even if you try to avoid the diamond problem by inheriting from very dissimilar classes, for instance a Pet class inheriting from Animal and say Property or something, and you make sure to avoid generic and common attribute identifiers like 'name', there are still a ton methods included to every class by default which can conflict, at least in Python. Maybe there are instances where they are fine in theory but my experience with them in production is ALWAYS frustrating. To any future or current developer out there: If you find yourself typing multiple-paragraph comments describing the quirks of something, maybe instead spend that time finding a better way which doesn't require it?
Python is hugely dynamic and has a bunch of duck-typing. Heck, I think that a person could have an fully constructed object that is an Animal and you could inject Pet into it, at run-type.
Multiple inheritance is generally used to combine a stateful class with a behavior class. Like having 'button' behavior which can be attached to an image or a label. Rather that for trying to do something crazy like combine an image and a label.
It's always baffled me that people use inheritance at all with non-abstract parents. In my experience inheritance rarely makes sense, and when it does, it only requires one abstract base class with multiple children. I've never needed grandchild classes or these stupidly complex inheritance hierarchies that people make UML diagrams for. That's how you overengineer your code and turn a simple problem into a complex problem and a bunch of "what ifs"... "oh well if Requirement A ever changes then we already have this abstract BeanManagerFactory class and implementing it would be trivial..." "if product ever needs this feature we could implement it easily, all we need to do is create a class for it and override this method from 5 parents up..." if you don't need it then don't build it ffs
Can I suggest you to stop using "age" as a property of a class (entity) in your examples? It teaches VERY BAD habits to beginners to ignore normalization of their data (class) structures. An age isn't a scalar, it's a function from the birth date and now. If you store it, it's value will expire in the period from milliseconds up to a year. Use a birth date/year instead or choose any other property that has an actual absolute value.
Actually the "Diamond Problem" can happen with Java8 thanks to default implementations in interfaces. Where functions are 100% equal and thanks to 2 different interfaces you have this exact problem. How does java solve it: The class has to actually decide which implementation it uses. So the user gets told please pick for us!
I could be incorrect, but I feel this argument only holds water as long as you only accept the concept of an is-a relationship and reject the idea of a has-a relationship. Whether you like using has-a relationships or not they are a CS concept that would work better with multiple inheritance. Also in addressing the statement "I have never seen a problem that couldn't be addressed without multiple inheritance" I would say that I doubt there exists a problem that absolutely needs inheritance period. I'm quite certain that, while redundancy is bad, it still compiles. I might also say that this extends over multiple inheritance as well. While I could obviously not come up with a problem that needed to be solved with multiple inheritance (duh) I could come up with an example where it may have slightly less redundant code and could be slightly more readable. Especially in the realm of several has-a relationships.
Amazing explanation! I have just one suggestion for future videos: I tend to see your videos at night, everything good when you’re writing code, but when you use the board it hurt my eyes! Haha Just a silly suggestion, really appreciate your videos! :)
I was wanting for multiple inheritance recently. I had a PythonScript class that acted as a large superclass for anything that was a script (entity script , item script). I also had a class called UserInterface which was a large superclass for classes that are UI (editorUI elements, Main menu UIs). I needed a UIScript class which would extend both and have the needed protected fields from both but it wasn't possible under the current system. UIScript extends PythonScript and within the script file, an object called ScriptedUI is constructed and used as the actual UI. Other than this recent problem, I would never have needed MI.
Seems to me what Java actually need is the friend keyword to access protected fields of another class (without the fuss of package private arrangements).
I'm learning java and started with intellij but then I switched to eclipse and do not look back. I like your older videos where I could follow along better since you use eclipse. Why did you switch to intellij, do you think it is better?
Hello John, Great content as always, you have a natural gift of explaining complex concepts, and I bet you can explain Design Patterns to a toddler. it will be delightful if you can upload a video on Java Streams API. Much Love.
Issues like this exist in any language, and are best resolved by discipline, or 'standards'. The better resolution IMO would be to force the descendant class to implement the duplicate method as though it were a 'virtual method'. The 'interface' just makes you code ALL the methods for EVERY class that needs it. One way I get around the limit of only one parent class is to have a class that has an instance of each additional class that I might want. No ambiguity of methods, since the same-named methods are called by explicit reference to the enclosed object(s). BTW, the resultant creature would be a 'chimera'.
Multiple inheritance is not designed to provide a dog+cat child diamond problem, in fact you can have compiler problems doing so. Multiple inheritance is to adress what was latter provided in Java by interfaces. So multiple inheritance is required in many many problems to provide elegant solutions about what is in an object. The reason is that you can inheritate from an implemented class and this is not posible with interfaces where you must rewrite everything.
When i stumbled across this "missing" feature it was due to game development. It is really useful when you have stuff like a position class with move methods, a rotation class with rotation methods etc and want to apply it for example to a player class. But usually if you run into that you already fucked up your project architecture so its fine i guess. A better solution would have been to force the programmer to pick a method, for example with @Override(Dog.class) protected void makeNoise(); Then the override annotation would actually be useful nowdays lol
There was also the idea, that you could be forced to implement the duplicate methods yourself, and the rest is standard behaviour. I think overriding one of more methods with the same name is no good way. Does java has super? (I think so) Than it is important, that you can say which one you want
And i think there can be incomplete classes (I think it must also be possible for interfaces) -> you have to similar functions with different return types, but everything else the same. > How do you know which one is needed
@@schwingedeshaehers My solution to this would be, to either use MyClass.myMethod(); for ambiguous calls or even allow blocks with a syntax like "using MyClass as super { ... }"
@@schwingedeshaehers I cannot happen. Unless you have different parameters, which is casual overloading then, you are forced to decide which class to implement. And having two methods with the same signature in one class is impossible anyways.
Considering that java now supports implementations on interfaces and you can implements from multiple interfaces... so if you have one methjod implementation by each interface, could you be running ons ome kind of diamon problem here?
Right, you can have default implementations in interfaces now. To answer your question, if you implement two interfaces that have the same method, both with default implementations, it just won't compile. You are then forced to either add your own implementation or remove one of the interfaces. Give it a try and check it out!
@@CodingWithJohn That's definition of multiple inheritance while banning diamond inheritance... But some people have to bend over backwards to pretend it's not. I now remember a few (~7 or maybe even more) years ago when I saw that Java got this feature - I was at work and started laughing and then saying to my co workers "is Java trying to become a useful language :) Thanks for reminding me :) So to be honest maybe the initial creator didn't like multiple inheritance but Oracle/later maintainers after the initial author left, certainly disagree with him :)
I feel like Java should have done something simillar to what Kotlin does with classes that have grand-parents (Fun fact, Kotlin kind of implement multi-inheritance, tho it is quite complicated and I never touched it) When a class is 3 layer of more, you can do super.function() to choose which version of the function you want So if we have ClassA, ClassB that is a subclass of ClassA and ClassC that is a subclass of ClassB, if they all implement the function "foo()", with ClassC, when you do "foo()" it will do ClassC foo(), if you do super.foo() (or super.foo()) it will do ClassB foo() instead and finally, if you do super.foo(), it will do ClassA foo() I feel like Java should have implemented something like that (detect when an ambigious function is called and cause an error if it cannot choose) Tho I fully agree that Multi-inheritance is extremely rarely useful
But there is one thing : Mixins. Java not having multiple inheritance, means it does not have mixins ! My use case was this one : I was using SPRING HATEOAS, and this framework _forces_ you to have "Resource classes" that extend some class : class MyResource extends HateoasResource. Our domain objects all had some common attributes (creationDate, lastModifiedDate, creator, updator, etc), and the *most elegant solution* would have been mixins.
I'll have to check more into that! I'm familiar with hateoas, but haven't used it in any real-world app as of yet. Looking at the documentation though (haven't tried this yet), can you use EntityModel as a kind of wrapper, and have be your domain class extending whatever you need?
@@CodingWithJohn Hm not sure, we were using "RepresentationModel", the way we did it was creating another Superclass containing the common fields, that works of course, but it needed a bit of refactoring. In the context of "extending existing code", that does not feel good to change a hierarchy, thus mixins were missed by me this time just for elegance. But I agree you can do without them :)
The (later) implementation of default methods in interfaces shows that the reason is bogus. A method reference can be ambiguous but there is a way to disambiguate it. Real life example of multiple inheritance: Woman is a subclass of Human, secretary is a subclass of human. Neither woman nor secretary are subclasses of each other.
@@CodingWithJohn Yes, it is ambiguous, so if you don't disambiguate then it's an error. public class Cog implements Cat, Dog { @Override public void makenoise() { if (Math.random() > 0.5) { Dog.super.makenoise(); } else { Cat.super.makenoise(); } } }
If I made a language, my pseudocode for the Cog would be: class Animal {...} class Cat inherits Animal {...} class Dog inherits Animal { function Fetch(...); ... } class Cog inherits Cat { from Dog import Fetch ... } Kinda feels more natural for the programmer, other than being simpler.
Hello . . I think 2 interface with same default method can have the same issue like dimand problem . But we must have to implement it and have to define which one we want to call. Like super.Interface.default();
When you implement two interfaces with the same default method, it's a compilation error that you can only resolve by implementing that method yourself
It should be the developer's choice!!!! The amount of bloated code that i have seen that could have been avoided if they just supported multiple inheritance is enormous. If it were just behaviour, interfaces are great! But with fields? Interfaces don't know what that is. And the diamond problem? It happens because of bad design, not multiple inheritance. Java could've just blocked the diamond problem if they were so concerned, halving the language capability is not the answer.
Guess what The beauty of object oriented programming languages is that you can understand everything by taking a example from real life And OOP too is inspired from real life examples So the reason most of the teachers prefer these examples of animal class etc Because it is easier to understand by this method , and if a person can understand these then there will be no issue to you to understand things in terms of programming 😅
@@DrSpooglemon well it is It's too a language but not to communicate with people , but with machines And the answer to your question that why everyone don't learn programming It depends on their interest No one chooses a field on the basis of toughness But if one does then 💀
I don't think Java needs multiple inheritance, but I do think to be more flexible it should at least support friend classes. Many problems that at first glance would need it could in fact be solved with a combination a member of the other class combined with the friend operator of C++. So why is there no friend operator in Java? And no I don't think package private concept cuts it.
Honestly, anyone that laid eyes on that feature in C++ should have rejected multiple inheritance. -I love C++, but that doesn't mean embracing every idea they throw into the standard.
Nice video: couple of comments. Someone somewhere mentioned that Erlang handles multiple inheritance particularly nicely. Being a Java programmer who doesn't want to expand to esoteric languages I have never bothered to find out if this is true or not. I find it odd/wrong that you draw the arrow in the class hierarchy from parent to child. It makes little sense that no parent know about its children and in reality no class knows about the classes that extend it. Not a big deal, but I had to get this off my chest. About interfaces, yes, they are useful and have their place. However with the kind of software that I develop I often want to know what happens when I call a particular method (most of the code is internal to the project so I can and need to check that). If the object type is an interface it is a nuisance cause the IDE does not know the implementing class and thus cannot take me to the code that actually gets called.
Do you guys observe one thing senior developer come youtubers like John code with mosh,Naveen Reddy from telsko, don't have hair on there head i think they are hiding dark side of IT industry.
7:45 That's a terrible argument for not having a feature. Everything can be written in asm, there's no reason for anything beyond the x86 instruction set.
let alone multiple inheritance.. even single inheritance is hard to maintain.. remember, top rule in design pattern, prefer composition than inheritance.
I really appreciate the way you take high level concepts and present them in a digestible manner. I would love to hear you talk about design patters in Java. I feel it's a topic that is somewhat ambiguous and I feel that your high level analysis of it would greatly help me and many others!
Spicy comment incoming:
So, I can tell that this is a beginner friendly channel, but it would've been nice to at least mention in passing that inheritance is a bad practice ("Composition over Inheritance"). Here's a few resources that have great coverage of this concept:
- I greatly appreciate that you've included "Effective Java" in the video description, which is a beautifully written book -- it actually covers this concept as Item 18, which is titled... "Composition over Inheritance".
- I'd imagine that you're also familiar with the "Design Patterns" book by "the gang of four" (another very classic book in the industry) which also covers the concept of "Composition over Inheritance" in the very first chapter (p. 18 of my copy of the book).
- Some languages such as Golang (the language that Google created for their own software engineers) go as far as to not even implement inheritance within the language.
The alternative to solution to inheritance would be "delegation", which is composition + forwarding. This is a rather clunky pattern in vanilla approaches to Java, but I saw that you thankfully have a video on Lombok, which has the "@Delegate" syntax sugar as an experimental feature.
I see you have some other videos that have already covered a lot of very awesome topics in a concise and beginner-friendly way, like Generics, Reflection ("meta-programming"), Lombok, Records (building block of algebraic data types), Checked vs Unchecked exceptions. The only unturned stone that I can actually think of is "Data vs Object", which Robert Martin covered in a great blog post over here: blog.cleancoder.com/uncle-bob/2019/06/16/ObjectsAndDataStructures.html
while I generally favor composition over inheritance, it's far from considered "bad practice" and is often the best way forward for extending pre-existing functionality. I feel like claiming that inheritance is bad practice is somewhat in-vogue. Granted it can (and often does) get messy, and so you *do* need to be careful with how you abstract things or else you definitely end up with a monster that can be difficult to tame. That being said, opportunities for Composition where it is not overly redundant should generally be preferred
John, you the definition of what makes a good teacher. You have passion, knowledge, and dedication. Teaching isn't a skill. It's simply someone who understands something so well that they can break it down to it's simplest form and explain it in a way without trying to show off. You just that, every teacher should learn from you!
maybe in this topic could have been mentioned implementation of method from two different Interfaces with same method signature
I definitely thought about it! Basically how it works is, as long as the interfaces don't both have default implementations, there's no real conflict to resolve. The class can still implement that method that both interfaces specify. If they do both have default implementations, and you don't specify your own, it's simply a compilation error.
The same logic could be applied to multi inheritance. The only thing that would be problematic are non-private fields.
Would be interesting to know why two similar methods but with different type parameters are not allowed in one class
@@nonswag4739 in some strict languages that actually exists
@@PieJee1 I know, that's why I'm wondering why java does not allow this
You explain these concepts really well. Even after 5 years of coding Java, I still learn from you
I have the same amount of experience and I agree with you!
If the diamond problem is the reason for not having multiple inheritance, then why can you implement multiple interfaces that could have the same default method implementation? In my opinion,
It would be neater if the subclass would treat a superclass method implementation conflict as an abstract method, so that you'd have to be explicit about which implementation you'd want (or if you wanted a whole different implementation). Only if the method was final it should give an exception.
This problem somewhat returned the moment when interfaces got default implementations in Java 8. So in some cases a developer is forced to choose which interface default implementation he wants to use, but it's compiler enforced and quite rare in practice. As for a diamond issue the bigger problem in my opinion are fields rather than methods. In case of methods you can choose an implementation as mentioned before, but in case of fields you can't just "pick" which field version you want to use safely without potentially messing up something.
I find the diamond problem argument a bit of a meme because of the existence of default interface methods since Java 8. By that I mean it already exists in the language and you have tools to resolve that conflict while preserving the multi inheritance of interfaces.
The more likely reason I can think of is performance - with single inheritance, class fields always have the same offset within the memory of an object and type casting becomes basically free.
I have actually tried to implement annotation interfaces in a class before and I was surprised when I saw you do it too.
And yes I made a class that implements Deprecated, and realized that the required methods are actually the annotation members, as well as the annotationType() method. And while testing this, I found out that annotation interfaces without any members are actually functional interfaces, and giving them the @FunctionalInterface annotation works.
I Really like the way you explain coding stuff, even things I already know I watch the video patiently and learn something new. The way you speak english is nice even for foreign like me. Thanks again John ! See you next time!
It has been clear for me that multiple inheritance is not necessary since I started programming in rust. There is no inheritance at all in that language. There are interfaces in rust however.
rust did it well. inheritance is unnecessary and encourages you to over-engineer your code. traits in rust are fantastic because you get exactly as much abstraction as you need without going overboard
Overall excellent video, citing Gosling and stressing the "philosophy of simplicity" of Java is spot on, but I think one should make the distinction that using interfaces only gives you the same advantages as multiple inheritance as far as polymorphism is concerned, but NOT as far as code reuse is concerned, and inheritance is at its core a code reuse technique.
But then again, there are other ways to achieve code reuse, like composition, so refusing multiple inheritance makes sense if you are after a language that maximise simplicity and not flexibility and power.
8:00 Well here's the sitch:
Cat is an abstract class written by someone else that you aren't allowed to change.
Dog is from a licensed library package which you don't have the source code for.
Your manager is telling you to implement Cog in 5 minutes since "everything's been done already".
8:06 I've had a couple instances where I've wished Java had multiple inheritance. It wasn't really the only solution, just the alternative was a messy approach that involved duplicating a lot of code.
We had this multiple times in our code base, although the problem mostly came up when some of the actual java base classes better should have been designed to be interfaces. Seems to be especially true in Java UI classes that did not change mostly due to compatibiltiy reasons...
and then one day you realized, the best solution is just to not use java
I'm curious if you had specific examples. I think in most cases, we've been conditioned to prefer composition instead of inheritance and I think in most cases, the projects I've worked on rely less and less on inheritance for behavior and really just the properties/values.
@@th3runaway I think the use cases I had which this would would have helped with are both instances where I don't have control over what the parent classes are doing.
From memory, (modding minecraft) one was adding functionality to both Villagers and Zombie Villagers.
The other was using the same model for two entities but generic constraits prevent me from doing that, so I have to make a "Proxy" class for the second that wraps the model for the first.
The explanation is very clear and concise. James Gosling would be envious.
Good video, especially at the end :)
There one case where the multiple inheritance is missing, it's when you want to inherit from a class that it's not yours and don't duplicate code.
For exemple, if you have an interface that allow to get/set data from a database with a standardized solution (use of getType() to know table, then fetch provided attribut) and give those function to 2 objects, then you can either duplicate the whole code, or create a common abstract object.
But what if you want to add this feature to object that can be create in database, like MyCat & MyDog, but you can't on the Animal, Cat & Dog because it's not your ?
Before Java 1.7, it was not possible without code duplication.
Since Java 1.8, you may try to provide default function on interface, but you still need a getType() which is not available in your interface.
You can trick java by creating this method in the interface, because if the method exist in at least one of your parent, compilation work.
The downside is that you need to declare an AnimaleLike interface to provide signature of all needed function to your own interface, so you still have a bit of a duplication.
I discovered your channel today, let me tell you, your content is incredible! I love how simplified yet informative your explanations are, it says alot about how well you know what you're doing, I love the jokes you implement here and there as well, the whole thing is very interesting and educational from start to finish, light hearted and well put together. perfect to my taste! 🎉
Another awesome video. Thanks John for your efforts. Could you please make a video for us about dependency injection (DI and IoC)?
John, just a great video, i would appreciate if you can have some more advanced course on Java such as concurrency, i would definitely pay to watch.
I've got one!! Please believe me :P I'm working on a graphing package in Java, and one of the superclasses (abstract) is Plot, from which inherit LinePlot and ScatterPlot (not abstract). I have been wanting to create a LineScatterPlot class, and have kept on thinking that this would have been a perfect time for multiple inheritance. But yes, I will find a way around it... :P
To me multiple inheritance is just another useful tool in the box that unfortunately is not available in Java. One appropriate use would be the implementation of modular classes that can then be combined into a whole range of different combinations. Coming from C++ I sometimes do miss that language feature.
Of course one can emulate that behavior with Java constructs like helper classes and/or default implementations in interfaces (which again introduces the oh-so-terrible diamond problem that doesn't actually exist in Java.).
At the end these workaraounds require me to spread code all over the place that IMO better should be kept together in a single class.
Of course one can do all kinds of stupid things using multiple inheritance. As with almost any other advanced tool.
Carpenters use nail guns. When used appropriately they increase productivity and allow to work faster and with more accuracy. Sure you can shoot yourself in the foot with a nail gun. That is why you never let the inexperienced apprentice use it unsupervised, you observe best practises and safety procedures and you always wear protective gear.
Only the Java language designers would come to the conclusion that nail guns should be banned altogether.
Hey John! Would be really cool if you made an explanation video for Futures, it seems like a feature like Optionals where it seems to be somewhat overlooked. Thanks!
Python developer here: Its always baffled me that people actually use multiple inheritance. Not only have I seen it in in multiple stack overflow answers and tutorials, but actually in production. Even if you try to avoid the diamond problem by inheriting from very dissimilar classes, for instance a Pet class inheriting from Animal and say Property or something, and you make sure to avoid generic and common attribute identifiers like 'name', there are still a ton methods included to every class by default which can conflict, at least in Python.
Maybe there are instances where they are fine in theory but my experience with them in production is ALWAYS frustrating. To any future or current developer out there: If you find yourself typing multiple-paragraph comments describing the quirks of something, maybe instead spend that time finding a better way which doesn't require it?
Python is hugely dynamic and has a bunch of duck-typing. Heck, I think that a person could have an fully constructed object that is an Animal and you could inject Pet into it, at run-type.
Multiple inheritance is generally used to combine a stateful class with a behavior class. Like having 'button' behavior which can be attached to an image or a label. Rather that for trying to do something crazy like combine an image and a label.
It's always baffled me that people use inheritance at all with non-abstract parents. In my experience inheritance rarely makes sense, and when it does, it only requires one abstract base class with multiple children. I've never needed grandchild classes or these stupidly complex inheritance hierarchies that people make UML diagrams for. That's how you overengineer your code and turn a simple problem into a complex problem and a bunch of "what ifs"... "oh well if Requirement A ever changes then we already have this abstract BeanManagerFactory class and implementing it would be trivial..." "if product ever needs this feature we could implement it easily, all we need to do is create a class for it and override this method from 5 parents up..." if you don't need it then don't build it ffs
Loved the video john! May you please making a video on interfaces?
An alternative could be to allow multiple inheritance for the cases without conflicts and only give out an error when a diamond happens...
Can I suggest you to stop using "age" as a property of a class (entity) in your examples? It teaches VERY BAD habits to beginners to ignore normalization of their data (class) structures.
An age isn't a scalar, it's a function from the birth date and now. If you store it, it's value will expire in the period from milliseconds up to a year.
Use a birth date/year instead or choose any other property that has an actual absolute value.
Actually the "Diamond Problem" can happen with Java8 thanks to default implementations in interfaces. Where functions are 100% equal and thanks to 2 different interfaces you have this exact problem.
How does java solve it: The class has to actually decide which implementation it uses. So the user gets told please pick for us!
At the end Java arrived to same solutions that C++ and other older languages arrived 20 years before
@@kikoalbiol Yeah, same for C#.
I could be incorrect, but I feel this argument only holds water as long as you only accept the concept of an is-a relationship and reject the idea of a has-a relationship. Whether you like using has-a relationships or not they are a CS concept that would work better with multiple inheritance. Also in addressing the statement "I have never seen a problem that couldn't be addressed without multiple inheritance" I would say that I doubt there exists a problem that absolutely needs inheritance period. I'm quite certain that, while redundancy is bad, it still compiles. I might also say that this extends over multiple inheritance as well. While I could obviously not come up with a problem that needed to be solved with multiple inheritance (duh) I could come up with an example where it may have slightly less redundant code and could be slightly more readable. Especially in the realm of several has-a relationships.
Great man
Great video
Great language
And a great "I don't believe you"
Amazing explanation!
I have just one suggestion for future videos: I tend to see your videos at night, everything good when you’re writing code, but when you use the board it hurt my eyes! Haha
Just a silly suggestion, really appreciate your videos! :)
I'll try and use a dark background on the board next time!
@@CodingWithJohn Thanks! :)
That must have been an intense discussion
I was wanting for multiple inheritance recently. I had a PythonScript class that acted as a large superclass for anything that was a script (entity script , item script). I also had a class called UserInterface which was a large superclass for classes that are UI (editorUI elements, Main menu UIs). I needed a UIScript class which would extend both and have the needed protected fields from both but it wasn't possible under the current system. UIScript extends PythonScript and within the script file, an object called ScriptedUI is constructed and used as the actual UI. Other than this recent problem, I would never have needed MI.
Default implementations on interfaces are similar to MI for Java, so you could have used that, probably.
Seems to me what Java actually need is the friend keyword to access protected fields of another class (without the fuss of package private arrangements).
Great elaboration, absolutely loved this video
Can you please make a video about the java9 module system.
I'm learning java and started with intellij but then I switched to eclipse and do not look back. I like your older videos where I could follow along better since you use eclipse. Why did you switch to intellij, do you think it is better?
Eclipse is deprecated and JetBrains is multiplatform
Do the math!
This cog class got my head grinding gears.
Great video as usual! You do a fantastic work, it’s appreciated, we need more people like you 🎉
This video is amazing. Thanks for sharing this important information! Thanks John :)
Well, John, very clear and to the point. I like it, thanks...
Hello John, Great content as always, you have a natural gift of explaining complex concepts, and I bet you can explain Design Patterns to a toddler.
it will be delightful if you can upload a video on Java Streams API.
Much Love.
I do have a toddler son, so I'll have to give that a try!
Issues like this exist in any language, and are best resolved by discipline, or 'standards'. The better resolution IMO would be to force the descendant class to implement the duplicate method as though it were a 'virtual method'. The 'interface' just makes you code ALL the methods for EVERY class that needs it. One way I get around the limit of only one parent class is to have a class that has an instance of each additional class that I might want. No ambiguity of methods, since the same-named methods are called by explicit reference to the enclosed object(s).
BTW, the resultant creature would be a 'chimera'.
Java rejected multiple inheritance to prevent John from creating Cat-Dog
XD
For instance, since makeNoise() is a behavior, could be implemented as an interface describing better animals possibilities
Multiple inheritance is not designed to provide a dog+cat child diamond problem, in fact you can have compiler problems doing so. Multiple inheritance is to adress what was latter provided in Java by interfaces. So multiple inheritance is required in many many problems to provide elegant solutions about what is in an object. The reason is that you can inheritate from an implemented class and this is not posible with interfaces where you must rewrite everything.
When i stumbled across this "missing" feature it was due to game development. It is really useful when you have stuff like a position class with move methods, a rotation class with rotation methods etc and want to apply it for example to a player class. But usually if you run into that you already fucked up your project architecture so its fine i guess. A better solution would have been to force the programmer to pick a method, for example with @Override(Dog.class) protected void makeNoise(); Then the override annotation would actually be useful nowdays lol
There was also the idea, that you could be forced to implement the duplicate methods yourself, and the rest is standard behaviour. I think overriding one of more methods with the same name is no good way.
Does java has super? (I think so)
Than it is important, that you can say which one you want
And i think there can be incomplete classes (I think it must also be possible for interfaces) -> you have to similar functions with different return types, but everything else the same. > How do you know which one is needed
@@schwingedeshaehers My solution to this would be, to either use MyClass.myMethod(); for ambiguous calls or even allow blocks with a syntax like "using MyClass as super { ... }"
@@raphaelmateusdasneves772 we have a function in one class that returns an Integer, and one, that returns a string. -> how should that be handled?
@@schwingedeshaehers I cannot happen. Unless you have different parameters, which is casual overloading then, you are forced to decide which class to implement. And having two methods with the same signature in one class is impossible anyways.
we want more conceptual java video
like: Streams
Considering that java now supports implementations on interfaces and you can implements from multiple interfaces... so if you have one methjod implementation by each interface, could you be running ons ome kind of diamon problem here?
You can't implement a method in an interface.
Hope this helps 🙌
Right, you can have default implementations in interfaces now.
To answer your question, if you implement two interfaces that have the same method, both with default implementations, it just won't compile. You are then forced to either add your own implementation or remove one of the interfaces.
Give it a try and check it out!
@@cyberkiller83 Yes, that's right.
@@CodingWithJohn Thank you John. I love your videos, i feel they make me a better developer.
@@CodingWithJohn That's definition of multiple inheritance while banning diamond inheritance... But some people have to bend over backwards to pretend it's not.
I now remember a few (~7 or maybe even more) years ago when I saw that Java got this feature - I was at work and started laughing and then saying to my co workers "is Java trying to become a useful language :) Thanks for reminding me :)
So to be honest maybe the initial creator didn't like multiple inheritance but Oracle/later maintainers after the initial author left, certainly disagree with him :)
I feel like Java should have done something simillar to what Kotlin does with classes that have grand-parents
(Fun fact, Kotlin kind of implement multi-inheritance, tho it is quite complicated and I never touched it)
When a class is 3 layer of more, you can do super.function() to choose which version of the function you want
So if we have ClassA, ClassB that is a subclass of ClassA and ClassC that is a subclass of ClassB, if they all implement the function "foo()", with ClassC, when you do "foo()" it will do ClassC foo(), if you do super.foo() (or super.foo()) it will do ClassB foo() instead and finally, if you do super.foo(), it will do ClassA foo()
I feel like Java should have implemented something like that (detect when an ambigious function is called and cause an error if it cannot choose)
Tho I fully agree that Multi-inheritance is extremely rarely useful
can you do a video on sockets?
Wanna see a video on Streams 😁🙏
You explain everything so well - you've really been helping me in college :)
Hello, please a vídeo of Functional Interfaces. Predicate, Consumer, Supplier
But there is one thing : Mixins. Java not having multiple inheritance, means it does not have mixins ! My use case was this one : I was using SPRING HATEOAS, and this framework _forces_ you to have "Resource classes" that extend some class : class MyResource extends HateoasResource. Our domain objects all had some common attributes (creationDate, lastModifiedDate, creator, updator, etc), and the *most elegant solution* would have been mixins.
I'll have to check more into that! I'm familiar with hateoas, but haven't used it in any real-world app as of yet. Looking at the documentation though (haven't tried this yet), can you use EntityModel as a kind of wrapper, and have be your domain class extending whatever you need?
@@baranosiu as far as I know multiple inheritance and mixins are two different things, mixins can be used to copy methods to prototype
@@CodingWithJohn Hm not sure, we were using "RepresentationModel", the way we did it was creating another Superclass containing the common fields, that works of course, but it needed a bit of refactoring. In the context of "extending existing code", that does not feel good to change a hierarchy, thus mixins were missed by me this time just for elegance. But I agree you can do without them :)
The (later) implementation of default methods in interfaces shows that the reason is bogus. A method reference can be ambiguous but there is a way to disambiguate it.
Real life example of multiple inheritance: Woman is a subclass of Human, secretary is a subclass of human. Neither woman nor secretary are subclasses of each other.
If a class implements two interfaces with default implementations of the same method signature, it's a compilation error.
@@CodingWithJohn Yes, it is ambiguous, so if you don't disambiguate then it's an error.
public class Cog implements Cat, Dog {
@Override
public void makenoise() {
if (Math.random() > 0.5) {
Dog.super.makenoise();
} else {
Cat.super.makenoise();
}
}
}
I couldn't stand 999 likes so... i made it 1000
Thanks! Now nobody better like it anymore so we keep it at a nice even number.
Very beautiful and interesting work!!
If I made a language, my pseudocode for the Cog would be:
class Animal {...}
class Cat inherits Animal {...}
class Dog inherits Animal
{
function Fetch(...);
...
}
class Cog inherits Cat
{
from Dog import Fetch
...
}
Kinda feels more natural for the programmer, other than being simpler.
Hello . . I think 2 interface with same default method can have the same issue like dimand problem .
But we must have to implement it and have to define which one we want to call.
Like super.Interface.default();
When you implement two interfaces with the same default method, it's a compilation error that you can only resolve by implementing that method yourself
Could you make a video explaining the principles SOLID, DRY, KISS, and more?
Never liked oop
I would say classes in general are problematic. And should be removed from languages. Like in GO, Rust, Zig...
Meanwhile Javascript Cog says: MeowWoofGrrr 😅
So, does java support multiple inheritance…..????
It should be the developer's choice!!!! The amount of bloated code that i have seen that could have been avoided if they just supported multiple inheritance is enormous.
If it were just behaviour, interfaces are great! But with fields? Interfaces don't know what that is. And the diamond problem? It happens because of bad design, not multiple inheritance. Java could've just blocked the diamond problem if they were so concerned, halving the language capability is not the answer.
Have you never heard of a catdog!! It’s a Nickelodeon cartoon created by a c++ developer who imagined it after using multiple inheritance!! Like duh,…
I think a good example would have been "animal" "Lion" "Tiger" and "Tigon" because those are real things...
Hahaha, this was awesome! I chucked at the "cog" fetch of "the cat does it if it feels like it" 😆
Why are these OOP examples always something stupid like 'Cat inherits from Animal'? No one has ever written a program that requires an 'Animal' class.
Guess what
The beauty of object oriented programming languages is that you can understand everything by taking a example from real life
And OOP too is inspired from real life examples
So the reason most of the teachers prefer these examples of animal class etc
Because it is easier to understand by this method , and if a person can understand these then there will be no issue to you to understand things in terms of programming 😅
@@EnfieldicProgramming is nothing like real life. Otherwise everyone would be doing it.
@@DrSpooglemon well it is
It's too a language but not to communicate with people , but with machines
And the answer to your question that why everyone don't learn programming
It depends on their interest
No one chooses a field on the basis of toughness
But if one does then 💀
I don't think Java needs multiple inheritance, but I do think to be more flexible it should at least support friend classes.
Many problems that at first glance would need it could in fact be solved with a combination a member of the other class combined with the friend operator of C++.
So why is there no friend operator in Java? And no I don't think package private concept cuts it.
Great video! Thanks! 👌👍
Honestly, anyone that laid eyes on that feature in C++ should have rejected multiple inheritance. -I love C++, but that doesn't mean embracing every idea they throw into the standard.
Thats the reason for me to Extends the Suscribe class and implement the Like interface ❤ Derpalerp!!
Nice video: couple of comments.
Someone somewhere mentioned that Erlang handles multiple inheritance particularly nicely. Being a Java programmer who doesn't want to expand to esoteric languages I have never bothered to find out if this is true or not.
I find it odd/wrong that you draw the arrow in the class hierarchy from parent to child. It makes little sense that no parent know about its children and in reality no class knows about the classes that extend it. Not a big deal, but I had to get this off my chest.
About interfaces, yes, they are useful and have their place. However with the kind of software that I develop I often want to know what happens when I call a particular method (most of the code is internal to the project so I can and need to check that). If the object type is an interface it is a nuisance cause the IDE does not know the implementing class and thus cannot take me to the code that actually gets called.
An interface tells you what the class does, not HOW it does it. Your explanation on interfaces is confusing when saying "what you are".
Thanks John, keep up the great work. I always look forward to watching your next video.
Do you guys observe one thing senior developer come youtubers like John code with mosh,Naveen Reddy from telsko, don't have hair on there head i think they are hiding dark side of IT industry.
Multiple inheritance brings more grief than benefit.... Never 😉 keep it simple
7:45
That's a terrible argument for not having a feature. Everything can be written in asm, there's no reason for anything beyond the x86 instruction set.
Oh, finally I got it! That's how CatDog appeared! Alone in the world is the little CatDog!
Am I correct in saying that Method Resolution Order is that ruleset that other languages use to decipher multiple inheritance prioritisation?
I wish java allows operator overloading like in C++ and python though.
why wouldnt you just make a "cog" as a child of animal with parameters from both dogs and cats?
please make video on java multithreding and cuncurrency
It should be called genetic engineering instead of inheritance! Or maybe Mutate.
let alone multiple inheritance..
even single inheritance is hard to maintain..
remember, top rule in design pattern, prefer composition than inheritance.
What's the point of implementing interfaces if I then have to write again every single method that I implemented in the class?
I'm here because I am preparing for a java interview
I has asked my teacher in college the same question. Didn't got any answer
Idea for next topic:
Java Agents
What if I have an Object class that is Concrete, Connective and Movable?
Is it possible to declare an optional methods in an interface, or all methods declared in an interface must be implemented?
I can hear still hear the remnants of my professor screaming these OOP concepts into my brain
I would allow multiple inheritance and require that common inherited method to be overridden.
What's the difference between an interface and an abstract class in Java?
An interface only has abstract methods
I saw "dog" and "cog" and thought it was LeetCode 127
I've searched your channel high and low for a video on switch statements. Now I have separation anxiety! :*(
"I dont beleive you" was really good :))
Could you teach c# in this way coz it's very effective
It would have been better if OOP was rejected all together.