Inheritance vs Interfaces in C#: Object Oriented Programming

Поделиться
HTML-код
  • Опубликовано: 12 сен 2021
  • Inheritance is a big part of object-oriented programming, as are interfaces. However, the two can often get confused. Knowing when to use inheritance and when to use an interface is important. In this lesson, we are going to talk through when to use inheritance and when to use an interface instead. Then we will look at an example to illustrate these principles by first getting it wrong and then following the best practices to use both interfaces and inheritance each in the best possible manner.
    Full Training Courses: IAmTimCorey.com
    Source Code: leadmagnets.app/?Resource=IvsI
    Mailing List: signup.iamtimcorey.com/

Комментарии • 248

  • @tshandy1
    @tshandy1 2 года назад +60

    Very helpful info. I've used inheritance and interfaces for years and never thought about all the criteria you've presented here. I liked the example of a "rental vehicle," which as you demonstrated, quickly fell apart as more business use cases (motorboat, sailboat, etc.) emerged. This happens in real life, as you know, which is why I always prefer to spend my first few hours (or days, even) on a new project learning about the business context or problem domain. Too many developers, who should know better, just want to just write code -- which is going to keep them at the "junior" level making rookie mistakes. "How well do you understand the business context?" might be one of the criteria I would add to your list when determining whether inheritance makes sense.

    • @IAmTimCorey
      @IAmTimCorey  2 года назад +6

      Excellent point. Thanks for sharing.

    • @Kaboomnz
      @Kaboomnz 2 года назад +1

      The people who don't study the business context and just code are hired to just code, not sure why you'd dunk on them. If however you're talking about freelance developers then I have to say I've never met one yet that is so incompetent that they'd ignore the business context of what they're developing.

    • @joeman123964
      @joeman123964 Год назад +2

      to be fair that's why we have business analysts to do meeting with, they layout everything we need with future projections and implementations we'll need to worry about in the near or far future

  • @PWXcptcrunch
    @PWXcptcrunch Год назад +11

    Well done Tim! I am a senior developer with years of experience using these concepts and just when I think I already know the topic I always learn something new, or at least a new way of approaching it from you.

  • @mel8969
    @mel8969 Год назад +4

    I'm always amazed at how you make complex information so easy to understand and how deeply you go into the subjects Tim.

  • @danielvillalba4457
    @danielvillalba4457 2 года назад +6

    Great video Tim, thanks for sharing, Composition over Inheritance when possible is my gold rule.

  • @keithmason1841
    @keithmason1841 2 года назад +1

    Thank you Tim. Not just the right answers, but more important in this case: the right questions. You provided both.

  • @a.porteghali7402
    @a.porteghali7402 2 года назад +4

    I've searched a lot after watching SOLID series to figure out how best to use interfaces. This excellent tutorial helped me a lot to better understand it. Thank you so much for shedding light on this.

    • @tomthelestaff-iamtimcorey7597
      @tomthelestaff-iamtimcorey7597 2 года назад +1

      Thanks for looking to Tim for help on the topic.

    • @a.porteghali7402
      @a.porteghali7402 2 года назад +2

      @@tomthelestaff-iamtimcorey7597 Just want to add this tutorial is also the best one to get the DRY Concept across. Worth watching several times.

  • @ChidambaramVelayudham
    @ChidambaramVelayudham Год назад

    Well articulated and explained. Thank you for your commitment to the community by sharing the knowledge continuously !

  • @annayeung789
    @annayeung789 Год назад +2

    This is video really deserves more views and likes!! Thanks for explaining this topic in a very clear and substantial way

  • @clnarain
    @clnarain 2 года назад +4

    As always excellent and very informative. It will be nice if you can do another video on composition and it's implementation in C#. I always find it hard to understand the scenarios in which to use either of these

  • @kualalumpur5757
    @kualalumpur5757 2 года назад +1

    This is a very useful video. Thank you. It clarifies the difference of use between interfaces and inheritance with sufficient complexity, not just in theory.

  • @Arekadiusz
    @Arekadiusz 2 года назад

    Pretty awesome to see you still uploading!

  • @bravo906
    @bravo906 2 года назад +4

    Hey Tim, It was a good video. You made a good point when you said RentedVehicle was stretched too much and I think it would have broken Liskov substitution principle as well.

  • @torrvic1156
    @torrvic1156 11 месяцев назад +1

    Amazing explanation! Years ago I stumbled on a problem like this with a bank account class and I banged my head against the wall as to how it should be designed properly.
    But also you told as to how search for the stuff on the exact channel you need. I am very grateful for you for telling me this! My bad…I didn’t knew it.

  • @abdelghanidraoui781
    @abdelghanidraoui781 Год назад +2

    Million thanks to the great teacher Tim !

  • @xcyron
    @xcyron Год назад +2

    After your SOLID series i started to wonder about this topic and it seems like you got an answer for everything :)
    Thanks!

  • @jeanpaulroi
    @jeanpaulroi 2 года назад +20

    Hello Mr Corey. I also saw the videos about SOLID - the topic "Inheritance" vs "Interfaces" were already mentioned - very good lessons, thanks for that! However, I still have trouble figuring out what is the best use for "Is-A-Relationship" and "Has-a-Relationship" (Inhertiance vs. Composition). And: There are also cases where you can decouple the code with the use of delegates instead of Interfaces, or even with generics in fewer cases. I would appreciate a video showing best practice examples for these topics. Cheers

    • @GuRuGeorge03
      @GuRuGeorge03 2 года назад +2

      delegates and generics are just shortcuts for certain design patterns (depends on their specific use case and implementation). they aren't recommended if you want to write truly SOLID code. Many languages offer features like that if you are "lazy" but that doesn't mean that using them is always the best choice :)
      side note: especially if u work in a team where people usually aren't experts in a certain language then keeping to language features that all languages implement can be a huge advantage.

  • @LifeWithSeb99
    @LifeWithSeb99 2 года назад

    I actually wondered about it recently, good timing!

  • @187BulletProof1
    @187BulletProof1 2 года назад +1

    Amazing video for a novice programmer such as myself, all made clear and logic is on point and explained well 👏

  • @rjrrclaro
    @rjrrclaro 2 года назад +2

    Great content dude. Keep up the good work. Greetings from Portugal 🇵🇹

  • @leaoaugusto
    @leaoaugusto 2 года назад +1

    Hey Tim. Thank you much. Im learning from your videos so I can be a better Python programer. Your videos are awesome! My best regards from Argentina!

  • @davindersra
    @davindersra 2 года назад +1

    You are a real man Corey great work you are doing

  • @Soccercrazyigboman
    @Soccercrazyigboman 2 года назад

    I don't ever like videos and comment on them but I had to on this one. Because it breaks the topic down and gives examples of both in easy to grasp way to explain this murky situation between inheritance and interfaces. Thanks a lot from a new developer!

    • @IAmTimCorey
      @IAmTimCorey  2 года назад

      Awesome! I’m glad it was so helpful.

  • @KouroushMetal
    @KouroushMetal 2 года назад

    Very good discussion! thank you!

  • @muhammedeminokcu1327
    @muhammedeminokcu1327 2 года назад

    Very helpfull, Understandable perfect talking. Thank you...

  • @JamesMCrutchley
    @JamesMCrutchley Год назад +1

    Wow. Never new that about cars. I have never operated a car that used a physical key. Loved the video. Learned some good practices and I like the demonstrations of what to do and not to do.

  • @luismarquez6653
    @luismarquez6653 Год назад

    Thank you for making it very easy to process!

  • @sharathgoud1573
    @sharathgoud1573 2 года назад +1

    Thank you @Timcorey

  • @Davini994
    @Davini994 2 года назад

    This is great. I've come from basic, without any of the structure of modern languages. Good design and use of the features available is difficult, and often taken for granted by people familiar with them, for example the book I started with, which spent an age on things obvious to me but had little of this sort of thing.

  • @orijueladave5497
    @orijueladave5497 Год назад

    This is very helpful, Thank you for sharing.

  • @MrWkirsten
    @MrWkirsten 7 месяцев назад

    Fantastic video. Thank you so much

  • @rolandwatz7797
    @rolandwatz7797 10 месяцев назад

    Thanks a lot for this Video Tim. It helped a lot at my current project. Reusing code instead of retyping rocks. ;-)

  • @maxron6514
    @maxron6514 2 года назад

    Bro this is the best explanation for interfaces ever

  • @georgecall1543
    @georgecall1543 2 года назад +1

    Great videos, really learn a lot from you. Thanks

  • @GToast01
    @GToast01 Год назад

    it took me some time to understand how interfaces should be applied and so on. but this video, damn. great lesson, thank you for your work!

  • @geekbait7019
    @geekbait7019 2 года назад +1

    Tim, what is your stance on combining Interfaces? for example would you create an interface like this IRentalCar : IRental, ICar ? i keep getting sucked into putting all my inheritance in combined interfaces. do you think this is bad practice?

  • @andreisolero192
    @andreisolero192 2 года назад +1

    Tim, more of this please :0

  • @lemonlee9493
    @lemonlee9493 2 года назад

    Great video!

  • @mustafaezici7702
    @mustafaezici7702 Год назад

    Its the best video that ı have seen about inheritance and interface

    • @IAmTimCorey
      @IAmTimCorey  Год назад +1

      Thank you! I’m glad it was helpful.

  • @ranjanadissanayaka5390
    @ranjanadissanayaka5390 3 месяца назад +1

    thanks for the video sir.

  • @Alex-ol4bv
    @Alex-ol4bv 2 года назад +1

    Great example, thank you. I was wondering, how would you design the database for this rental scenario? Would you rather have one "big" table that holds all rentals, or one separate table for each concrete implementation of IRental?

    • @IAmTimCorey
      @IAmTimCorey  2 года назад +3

      It depends on what type of database I am using. If I am using a SQL database, I would probably have one rental table but then I would have a table for each type of IRental item. Those items would refer back to the rental table's id to link them to the main table. That's just a thought off of the top of my head. I would have to test it out to see if it is the best idea. If I were using a MongoDB database then I would just store the objects with their data in one collection. We could break them back out into various models when we get them back to C#.

  • @UmanPC
    @UmanPC 2 года назад

    Tnx a lot Tim

  • @afrostewie
    @afrostewie 2 года назад

    Hi Tim, interesting video, thanks for sharing this knowledge!
    Sometimes I face the problem that (following your example) IRental would need some common logic. For example when setting the CurrentRenter property we would like generate internally some ID from that (i.e. the setter needs some logic implemented). How would you handle this situation?
    If we follow what you suggest at the end of the video about code sharing, then the actual call to the common shared code would be duplicated in each IRental property implementation…
    Or in this case should we create a base class "Rental" which implements IRental, and then LandVehicle would inherit from it?

    • @AnotherFancyUser
      @AnotherFancyUser 2 года назад +1

      You can't have multiple inheritance.
      Plus you would be making the same mistake with the different type of vehicles

  • @stavrosk.3773
    @stavrosk.3773 2 года назад

    Smooth video.

  • @franciscooliveira8585
    @franciscooliveira8585 9 месяцев назад

    Thank you!

  • @demps1bm1
    @demps1bm1 7 месяцев назад

    Great video. Generally, I do not use inheritance unless I have a real reason to do so. I deal with a lot of CRUD operations and, while I could contrive some sort of inheritance scheme, I don't because it adds needless complication to the code. As you pointed out, inheritance is not about sharing code but about hierarchies that frequently do not exist or only exist because they are contrived (although sometimes they do -- standard classroom techniques of animals/mammals/humans or canines or bats or whatever.)
    Something that many may not be aware of is that before object oriented code there was structured code. There were brilliant coders in the 1980's and they shared code through structured libraries. Object oriented code is not necessarily better than structured code, it is just different. However, in today's world understanding objects is a requirement unless you are doing systems programming in C or Assembler.
    Interfaces are a different matter. I use them all the time because I use dependency injection so that I can decouple classes and unit test my code. I do everything I can to break my code with these tests and I frequently succeed.
    I also liked your discussion of DRY. The real purpose of DRY is so that if you change a method one place you do not have to change the same method (repeated) or a similar method in your code.
    Thank you so much. I hope that others, including managers, are paying attention.

  • @TheKevlar
    @TheKevlar 2 года назад +2

    The conversation of modeling the real-world always comes up in our design team meetings. This video is worth watching for ALL dev levels because Interfaces are underutilization and this can cause a considerable amount of code refactoring when expanding systems into other industries...

  • @wolfpack4128
    @wolfpack4128 Год назад

    This is sp helpful. The place I am getting stuck is how I would bring in my NoSql data and know which object to use to import it. How do I store a new sail boat in a NoSql db and then bring it into memory in the right SailBoat object?

  • @chetranqui
    @chetranqui 2 года назад

    I'm currently studying for my first ever junior dev interview and this is soo timely! Thanks for the greater understanding of OOP. :-)
    Now for a refresher on abstract classes and methods...

    • @tomthelestaff-iamtimcorey7597
      @tomthelestaff-iamtimcorey7597 2 года назад +1

      Good luck on your interview. Check out Tim's Dev Questions for other videos the help with your interview prep.

    • @chetranqui
      @chetranqui 2 года назад +1

      @@tomthelestaff-iamtimcorey7597 Just as a follow-up: I got the job! Thanks again for the encouragement and resources y'all have provided!

  • @juanwagner6221
    @juanwagner6221 2 года назад

    Hi! Great content. Greetings from Argentina. What do you think about asking for implementation type check when working with interfaces? Doesn't it makes the client to know about the specifics of the implementation? I've been strugling with that idea recently.

    • @LukeCloudrunner
      @LukeCloudrunner 2 года назад +1

      I would prefer to avoid checking the implementation type and instead use multiple interfaces to handle the cases where the implementation is different enough to require checking. For example, a toy car and a real car can might have the interface IHoldsPassengers. However the passengers in a toy car are different to the passengers in a real car, so instead I may use a new interface IHoldsToyPassengers for the toy car so that I don't need to check whether the car is a toy or not. The interface itself becomes the checking point and the client doesn't need to know any details about how the interface is implemented.
      Interested to know if you had any other thoughts on this one.

    • @juanwagner6221
      @juanwagner6221 2 года назад

      @@LukeCloudrunner Well, I took an aproach similar to yours. My case was about an order creation process where items could be related to products, generic items non product related, discounts, combos, etc... Each one of them having different rules and data, but sharing part of that data by being "order details". At first, I created an IOrderDetail interface and passed an array of IOrderDetails to the order creation. But then i was checking types of elements for logic implementation and persistance. So I decided to create an "OrderCreationRequest" object that have a method for each detail type like "addProductDetail" or "addDiscountDetail". That way I can tell the clients of the order creation process which details can they pass, getting rid of the type checking.

  • @ericxu7023
    @ericxu7023 2 года назад

    Hey Tim,thanks again for this great video. I still have a small question though, at 35:00 when you are trying to show the inevitable repetition that interface brings, why can't we just put those three properties into a rental class, and just inherit from this base rental class?
    Just imagine if we need to add a new property like say "PriceRange" into the rental interface, don't we have to change all the classes that implemented this interface?

    • @ericxu7023
      @ericxu7023 2 года назад +1

      Oh, I see multiple class inheritance is not allowed in C#, so classes have to derive from one single base class, that makes much more sense why we have to use interface now. Thanks for this great example

    • @IAmTimCorey
      @IAmTimCorey  2 года назад +1

      I am glad I was able to clear that up.

  • @williamliu8985
    @williamliu8985 2 года назад +3

    Tim, could you let us know what`s your opinion about the idea "prefer composition over inheritance"?

    • @michaelnurse9089
      @michaelnurse9089 2 года назад

      Since I came across this I have been noticing that this principle is way bigger than just computer science. It holds true almost everywhere.

    • @IAmTimCorey
      @IAmTimCorey  2 года назад +2

      I agree with the statement. Just remember that the key word there is "prefer". There is a time for each.

    • @awmy3109
      @awmy3109 2 года назад

      Especially for modelling "relational" database entities. I avoid inheritance there even when it makes sense.

  • @cristianjuarez1086
    @cristianjuarez1086 2 года назад +2

    34:22 why dont make IRental a class instead of an interface and just inherit from there too?

  • @ivanpesenti1138
    @ivanpesenti1138 2 года назад

    Hi Tim,
    foremost, thank u for the great video and for your time.
    Personally, I don't like having the props repeated as in BetterOODemo.
    Could be a valid approach to create a base abstract class and implement the interface (IRental in this case)?
    With that, the other classes can inherit from this base class and override the methods that have a different logic.
    Did you see any downsides with this approach?

    • @IAmTimCorey
      @IAmTimCorey  2 года назад +1

      Then your classes would all have to be rentals, which would not apply if you decided to sell some of the older vehicles (a common practice). Repeating props is not a big deal. Be careful not to let preferences impact performance.

    • @ivanpesenti1138
      @ivanpesenti1138 2 года назад

      Okay Tim! Maybe I've to do more research about this topic to better clarify it. Anyway, thanks for your point of view 😊

  • @thatguyty96
    @thatguyty96 Год назад +1

    If only we could actually rent tanks, LOL! Jokes aside, thanks always Corey.

    • @IAmTimCorey
      @IAmTimCorey  Год назад +1

      There is a place in Europe that rents tanks for goofing off. I’d love to try it someday.

  • @Niko-nh9gs
    @Niko-nh9gs 2 года назад +1

    Danke!

  • @bimsherwood7006
    @bimsherwood7006 2 года назад

    I've been bit by the puts-you-in-a-corner issue a few times. Most of the time I reach for inheritance, I'm wrong. I can't remember the last time I legitimately needed it.

  • @stevennell3365
    @stevennell3365 Год назад +1

    Thanks

  • @asta9198
    @asta9198 2 года назад

    What if we want to add more properties to IRental, is that mean we have to go through all the files that implement the IRental and you think it is okay? To me, it is really hard to plan ahead. I am sorry i am still a noob!

  • @IocaIhost
    @IocaIhost 2 года назад

    What happens if we use the new “RUclips Thanks” feature? Do you actually get the money it costs to buy the celebration things? Or does it just highlight your video?

    • @IAmTimCorey
      @IAmTimCorey  2 года назад +1

      I do get the money (RUclips takes a 30% cut, though).

  • @kcvinu
    @kcvinu 2 года назад

    Hi, thanks for the video. I have a question. What's the equivalent of "if (r is Truck t) {}" part in VB ?

    • @kcvinu
      @kcvinu 2 года назад

      Do I need to cast it ?

    • @IAmTimCorey
      @IAmTimCorey  2 года назад +1

      Not sure. I haven't kept up on my VB. Sorry.

    • @kcvinu
      @kcvinu 2 года назад

      @@IAmTimCorey Okay, no problem.

  • @alfonsdeda8912
    @alfonsdeda8912 Год назад

    Hi Tim, thank you for your help.
    I have one doubt:
    -I practically have one base class with 4 properties, but there are other properties that each of them should be added only if the user enable that in settings,should I do as many interfaces with only one property as are other properties and construct different implementations or would you have another idea?
    Thanks in advance.

    • @IAmTimCorey
      @IAmTimCorey  Год назад

      Typically, you don't add properties based upon a user's choice. That sounds more like a set of boolean properties or a Dictionary of options. You shouldn't need multiple classes.

    • @alfonsdeda8912
      @alfonsdeda8912 Год назад

      @@IAmTimCorey Hi Tim, thank you for your response. I have a done a class with all properties and one dictionary that has the name of property like key and if is enabled like value and i pass to classes that need those settings, is a good idea?

  • @DevLearn-lv7nr
    @DevLearn-lv7nr Год назад

    Hi Tim @45:22 if (r is Truck t) - i dont get this - r is an interface "Irental" type and Truck t if of type "truck" how can you compare one against the other they are different types ??

    • @IAmTimCorey
      @IAmTimCorey  Год назад

      r isn't an interface. An interface cannot be instantiated. Instead, the variable knows that whatever is inside of it implements the interface. The actual type isn't IRental, though. We had to put a concrete type inside of it. So, we are checking to see if the concrete type inside of r is of type Truck.

  • @netsurfers9357
    @netsurfers9357 2 года назад

    Polymorphic behavior = Parent over the child (attributes passed to the parent), Inheritance = Child over the parent (attributes passed to the child), Abstraction = Filtering out the calls/attributes, Interface = Patterns with definition towards attributes like that of a quilt.

  • @nafisiancastle
    @nafisiancastle 2 года назад

    thanks

  • @Bare_Essence
    @Bare_Essence 2 года назад +1

    Sailboat is where you switch to "real" C++ and forget about limitations in languages on multiple inheritance; inherit from Vehicle and Motorized. :) Interfaces is a lukewarm response to a lack of multiple inheritance in framework languages. And in BetterOODemo, how to deal with bike? Or your matchbox car? It can be rented but no engine. These specifics will break any OO concept with or w/o interfaces just as it did in simple framework OO. The problem that I have with interfaces is the people start with interfaces. Great. Any future change now requires changes and functionality to every class that inherits from it. I have to answer the question of the additional element for every class; which still may vary. And your example about code reuse assumes your adding simplistic properties. My programs are rarely simple CRUD type classes. I see your point about the complexity of the thing matters, but it still requires repetition. Not being a violation of DRY is just an opinion/interpretation; IMO :) Changing types in the future could be a pain based on usage. But, thanks for sharing. Always like to hear how people deal and feel about subjects.

    • @Bare_Essence
      @Bare_Essence 2 года назад

      And I will check out your other videos related to DRY and other subjects. Thanks for sharing!

    • @tomthelestaff-iamtimcorey7597
      @tomthelestaff-iamtimcorey7597 2 года назад

      Thanks for joining the conversation and sharing from your experience.

  • @caleb_riordan
    @caleb_riordan Год назад +1

    So if we had the ability to inherit from multiple classes in C# (which we don't), that would basically replace interfaces? (except for the fact that interfaces are better to use for concepts that are not related to each other in a way that makes sense)

    • @IAmTimCorey
      @IAmTimCorey  Год назад +1

      Yeah, the fact that interfaces allow us to apply them to non-related classes is a big reason why they are better than multi-inheritance would be.

  • @lirilane5190
    @lirilane5190 2 года назад

    and what keyboard are you using? / i have brown "breakers" and a ducky one 2 TKL but i am thinking of changing it to a lower key cap one...

    • @IAmTimCorey
      @IAmTimCorey  2 года назад

      I use the Logitech MX Keys keyboard (not mechanical - it would be too noisy for video).

    • @lirilane5190
      @lirilane5190 2 года назад

      @@IAmTimCorey Wow nice thank you!! It looks very nice and has low profile keycaps too! :D

  • @ifeanyioraelosi7305
    @ifeanyioraelosi7305 2 года назад +1

    Can we investigate an often-used open source repository as a way to learn how the concepts are used in the real world?

    • @IAmTimCorey
      @IAmTimCorey  2 года назад +1

      I taught people how to do just that in this course: www.iamtimcorey.com/p/exploring-c-blazor-webassembly

  • @tiburciolapanak
    @tiburciolapanak 2 года назад

    Nice

  • @DalTron001
    @DalTron001 2 года назад

    How do interface and inheritances work with databases? If I use entity framework, then how does it map?

    • @ferooref7614
      @ferooref7614 2 года назад

      Here you can read about it docs.microsoft.com/en-us/ef/core/modeling/inheritance , cheers.

  • @chris5947
    @chris5947 Год назад

    Thank you, very well explained

  • @KZ-or1zq
    @KZ-or1zq 5 месяцев назад

    So what do you do with a rental boat? It has an engine you can turn on and it's not a land vehicle.

  • @eddykathrein563
    @eddykathrein563 2 года назад

    Hi, could someone point me to the source code download links?? "down-below"?? where?? Thanks

  • @jeffsherman9638
    @jeffsherman9638 2 месяца назад

    Hello Tim, is there a simple way to explain where to use inheritance and where to use Interfaces. It appears that both are used in various locations of a project which is something I think I need to understand. I think this is an important question that needs to be asked during the initial design phase of every new design project. Also, it looks like the biggest takeaway message is that multiple interfaces can be used in single classes while inheritances really cannot.

    • @IAmTimCorey
      @IAmTimCorey  2 месяца назад +1

      There are a few principles to follow. First, default to interfaces. Make yourself prove why you should use inheritance in a situation (not the reverse). Second, make sure that any inheritance follows it the "is a" relationship (car is a vehicle where car is not a truck). Third, don't try to use inheritance as a code-sharing-only option. Don't forget that we can share code by just creating another class that the initial class calls. No need for inheritance. Fourth, don't use inheritance just to pass down structure. If there is no code shared, why wouldn't you use an interface?
      The bottom line is that this is always going to be subjective in a general sense. It is only when you get to a very specific situation where you can determine what is best. That takes a lot of practice. Defaulting to interfaces won't burn you. Defaulting to or overusing inheritance will burn you.

    • @jeffsherman9638
      @jeffsherman9638 2 месяца назад

      @@IAmTimCorey thanks Tim for taking time out to help me! I see that’s your practice when you are creating your projects and tutorials. Just needed a deeper insight

  • @tongyinwang215
    @tongyinwang215 2 месяца назад

    The choice between inheritance and interfaces can be tricky sometimes. Experience and domain knowledge can be helpful sometimes. Below is my two cents.
    If we want some external library classes to have same behavior in our code logic, we are quite sure using interface is the better way because external library classes are not inherited from our base classes. We can create a class inherited from external library class and implements the interfaces we want.
    Interface is more flexible but have to write own implementations. One of the ways to reduce this shortage is use some default implementation classes like RentalHelper and reuse the function inside.
    Interface should be as simple as possible. It is a poor design if an interface has too many properties and functions. This interface should be splitted to smaller interfaces. Try to make one interface serve one purpose only.
    Inheritance still have some other advantages also like better grouping and understanding of class hierarchy, and able to encapsulate and share private/protected members within its children only.

    • @IAmTimCorey
      @IAmTimCorey  2 месяца назад

      Interfaces should be as big as you need them to be and no bigger. That may mean that they are rather large. It all depends on the situation. Trying to make them too small means you will need to be utilizing casting later on to get access to the other desired properties and methods that another interface has in it.
      As for the default implementations, DO NOT DO THAT. The default implementations are not designed for you to use them like inheritance. They are only there to protect your existing classes from breaking changes. If you use the default implementation as a "multi-inheritance", you cause a lot of problems in your application and you incur a lot of casts as you switch between interfaces in order to get access to those methods.

    • @tongyinwang215
      @tongyinwang215 2 месяца назад

      @@IAmTimCorey Thanks for your advice. I will try to digest.

  • @Antonio-lt1sp
    @Antonio-lt1sp 2 года назад +1

    So... what's the point of inheritance? Is there any situation where it is better than interfaces?
    P.S. great video as always!

    • @IAmTimCorey
      @IAmTimCorey  2 года назад +1

      It can provide an efficiency when you truly have a relationship. The key is just not to abuse it.

  • @lirilane5190
    @lirilane5190 2 года назад

    Why do you choose to precede the interface with an "I"? Do you not know that it is an interface by the text color /if you hover on it? I just got curious since i think i read in clean code that using the "type" in the name is unnecessary but i am not sure myself.

    • @IAmTimCorey
      @IAmTimCorey  2 года назад +1

      Using "I" for an interface is an industry standard. The reason for this is not to signal the type like "str" or "lng" used to for variables (Hungarian notation). Instead, it is to clearly identify two different things (interface vs inheritance) when seen after the class. Remember that you can only inherit from one class and order matters. This way, we quickly know if the class inherits from another class or if it only has interfaces. I know IDEs make this easier to understand, but remember that you aren't always reading the code in the IDE. Sometimes you read it on GitHub or in a text editor.

    • @lirilane5190
      @lirilane5190 2 года назад +1

      @@IAmTimCorey Thank you very much Tim for your elaborate reply, I am very grateful :D And very good points aswell. Loving your videos and will continue watching them. :D

  • @DoctorMGL
    @DoctorMGL Год назад +1

    11:50 anyway to set a shortcut to "move type to xxxx.cs" in a one shortcut click instead of going through the menu then clicking ?

    • @IAmTimCorey
      @IAmTimCorey  Год назад +1

      Not that I know of.

    • @DoctorMGL
      @DoctorMGL Год назад

      @@IAmTimCorey thanks for answering, my greetings :)

  • @lainwired3946
    @lainwired3946 8 месяцев назад

    Ive not finished the vid yet youre just adding the truck for me, but from reading ahead in the comments a bit, if you stopped the abstraction of RentalCar to LandVehicle, added the truck as a style in your enum and allow cars to have stuff like empty load capacity etc, then create WaterVehicle, LandVehicle, AirVehicle, etc, amd thwn wrap the logic about the rental and inventory information and the person renting it, the cost etc into a RentalContract class that contains a Vehicle of any type, plus this info. What do you think of this pattern? First time viewer btw enjoying the vid so far

    • @lainwired3946
      @lainwired3946 8 месяцев назад

      Aha, it seems you ended up doing this. Even used the bad LandVehicle name i didnt like either! Maybe SelfPropulsionVehicle and PassivePropulsionVehicle or something. That might work better to genericise.

    • @lainwired3946
      @lainwired3946 8 месяцев назад

      Just as a final comment, the reason id make the rental contract a class at the top is because you probably will have to manipulate and maybe query or store that data (to a file, db etc)
      I think itd be fair to do a rewrite if you syarted renting TVs etc, or split those off into their own programs with libraries and glue logic apps if you rewlly must. But i think having different systems for elelectronics, vehicles etc with very little shared abstractions - just the rental contract basically has to glue the concepts

  • @dineshfalwadiya3282
    @dineshfalwadiya3282 2 года назад

    Thumbs up from india 👍

  • @kellothermes5090
    @kellothermes5090 2 года назад +1

    A beginner C# developer here !
    What if I create Rental as a base class and inherit "LandVehicle" and "WaterVehicle" from it. Not only both of the derived classes would have access to the "Rental" class but also they can implement their own unique methods inside their classes.
    By doing this I can just inherit the "Rental" members from the Rental base class instead of implementing "Rental" class members in every single class which inherit from the Rental interface.
    Is this a possible solution for this problem ?

    • @IAmTimCorey
      @IAmTimCorey  2 года назад

      No, because not all LandVehicles are rentals. We sell some of them. Therefore, they would be inheriting from something that is no longer needed. Code repetition not the primary concern here. It is ok to have the repetition in order to maintain the proper hierarchy.

  • @andywalter7426
    @andywalter7426 2 года назад

    I found even with interfaces a person can be backed into a corner. I had the issue before. For example, I have interfaces for solitaire games. However, it became messy but could not create even more interfaces because was unable to come up with names. However, somehow I made it work. If some methods are not always needed, they just don't get called if I am creating a game that does not need them. In that case, raising exception is fine. Its also okay in some cases where if a method calls and does nothing, its okay because there was nothing to do. For the rental sample, if a person did not know enough ahead of time when they created the system, then it may not be a big deal if a startengine method was called. If there is no engine, then just won't do anything. In that case, it could be okay. Unfortunately, since naming is hard, some times if a person can't come up with better names, a clunky system can be better than no system.

    • @IAmTimCorey
      @IAmTimCorey  2 года назад +2

      Yes, you can definitely create too large of an interface. That's a planning problem. That's why the recommendation from SOLID (Interface Segregation Principle) is that you create smaller, composable interfaces instead of large, unmanageable interfaces. As for raising an exception when an unneeded method is called, while that's what you have to do, that's also a sign of a design failure. If at all possible, that needs to be reworked to not need that. I definitely think it is a big deal that you didn't think far enough ahead with an application that you worked yourself into a corner. While you cannot know everything, you can properly plan and build an application. Not overusing inheritance would have saved the developer in my example, even if they didn't know that we were going to rent sailboats. Trying to include rental information and vehicle information together in one inheritance structure was poor design. The solution is to use an interface for items that may not have a true relationship but that have related features. Inheritance should only be used for true relationships. Follow that principle and you will have very few cases where you have "extra" methods and properties. In fact, that should almost never happen.

  • @livelovecode
    @livelovecode Год назад +2

    Drop that keel and centerboard, raise the mainsail, and you'll see if a sailboat has an engine 😁

    • @IAmTimCorey
      @IAmTimCorey  Год назад +2

      I'll watch you do that from the dock.

  • @LukTeWodReg
    @LukTeWodReg 2 года назад

    It's a very nice video, but i can't get one small thing - why we can't take one abstract base class instead of IRental. Yes, i saw some comment below this video with the almost same question, but answer always about "We can't use multiple inheritance in C#", but where will be this multiple inheritance? One base class (we can call it RentalObject) and his childs - Landvehicle and Sailboat (better call with different name but not about it here). And landvehicle will have it's own childs - car, truck, etc. If we want some flexibility we can add some interfaces and combine it. Please, tell me where i am wrong with that model (sorry for my english). Yes, in this case inheritance just sharing properties, but this is a relationship and this will help us avoid repeating of code. Maybe here will be problem with SOLID, but (if it is, ofc, please tell me) main question about inheritance.

    • @IAmTimCorey
      @IAmTimCorey  2 года назад +2

      The issue is the relationship between the items. Is every boat a rental? Not if you are going to sell them when you are done. Then you have rentals in your inventory that you aren't going to rent. Then you have an issue because your core identity of each item you own is the fact that it can be rented, yet that's not always something you are going to do. Inheritance often puts you into a corner. My rule of thumb is to look at interfaces first and only use inheritance when it is totally clear and obvious. That means I pass up a number of opportunities to use inheritance. I'm ok with that. Don't think of inheritance as code-sharing. If that's all you are concerned about, create a helper class and call it from each class. You could create a RentalInfo class that has all of the rental information. You could then use it as a property on each rental item in your inventory. You could set it to null when you aren't renting the item. There are a lot of ways to share code without using inheritance.

    • @LukTeWodReg
      @LukTeWodReg 2 года назад

      @@IAmTimCorey Thanks for the answer. Didn't think about how the business logic might change and how the code would need to be changed.

  • @SharunKumar
    @SharunKumar 2 года назад

    17:39 isn't this a good example against using primitive types?

  • @martapfahl940
    @martapfahl940 4 месяца назад

    Would you agree that inheritence can be the result of refactoring multiple classes that repeat their code? Imagine I have 4 classes that evolved over time because we've added more and more features to our product and now we see oh hey we have repeated code, lets create a base class and inherit from it? Instead of creating a base class right at the beginning, make it a result of refactoring. Or am I wrong? I think this way I dont get into the problems from minute 24:30 where you say oh now this method doesnt make sense anymore to be in the base class.

    • @IAmTimCorey
      @IAmTimCorey  4 месяца назад

      It can be a refactoring step, but it doesn’t eliminate problems like I demonstrated since refactoring isn’t the end of future development.

  • @UmarAlFarooq
    @UmarAlFarooq Год назад

    I understand this is just an example but for all examples provided, this entire requirement can be resolved in the data layer with entity relationships. Very little needs to take place in the methods.

    • @IAmTimCorey
      @IAmTimCorey  Год назад +1

      No, that wouldn't resolve anything. StartEngine and StopEngine have nothing to do with a data layer and creating entity relationships in the data layer would not solve the issue of using various types in one list.

    • @UmarAlFarooq
      @UmarAlFarooq Год назад

      @@IAmTimCorey your various "types" in this example are basically data collections that can be related or have multiple types of data in a single table with a "Type" column as an FK. If you want a column to be optional, just make it nullable.
      "Start" and "Stop" engine are also kind of impractical examples for a rental company, which, in this example, is just returning some text after a simulation. That could be done with a stored procedure.
      I'm not trying to criticize your lesson. It is very well done, with one exception. There are times when you speak quickly and kludge some words together. A native English speaker might still fill in the gaps but many non-native speakers might find it difficult to actively do that.
      My critique is mostly for me to wrap my mind around the concept. WHY would we want to do things this way? I'm trying to evolve out of my hard-set database background and learn better ways of doing things but am finding it challenging to understand that through this example. A database table schema structure allows for multiple inheritances. Another concept I have not understood about OOP. Why limit the inheritance to one?? Things are so simple in the DB world. Why is this so overly complicated?

  • @kumaravelg2348
    @kumaravelg2348 3 месяца назад

    If need to Inherit more than one class what we will do?

    • @IAmTimCorey
      @IAmTimCorey  3 месяца назад

      You don't. You could have inheritance like this, though: ClassA inherits from ClassB. ClassB inherits from ClassC. In that way, ClassA has access to ClassB and ClassC methods, properties, etc.
      If you find yourself needing multi-inheritance (not like I listed above, but where Class A inherits from both ClassB and ClassC directly), you are probably using inheritance incorrectly.

  • @pvjewel
    @pvjewel 2 года назад

    RentalSailboat example was funny; Your RentalVehicle implies having engine, so you cannot inherit it or you need to make right abstraction

    • @pvjewel
      @pvjewel 2 года назад

      and, yes, you are not in a corner yet :)

  • @ayhamnasser495
    @ayhamnasser495 2 года назад

    I am really enjoying your videos, I have one suggestion is it possible to make the videos shorter

    • @tomthelestaff-iamtimcorey7597
      @tomthelestaff-iamtimcorey7597 2 года назад +2

      Thanks for the feedback. Tim believes in giving context for what he is teaching and that takes time. His goal is not entertainment or just to dump knowledge on you but true education. Someone more familiar with the topics can speed up the presentation with great benefit to them. Slowing it down or losing the key "Oh, that's why he..." moment is not a good option. It's a balancing act, right? Your feedback helps Tim find that mix, so thanks.

  •  2 года назад

    RelationShipKind {Has, Is, Implements}
    Inheritance: Is
    Interfaces: Implements
    Composition: Has

  • @KoaKBeatz
    @KoaKBeatz 2 года назад

    Whats the difference, when i can rename "interface" into "class" and "IRental" to "Rental". What is the purpose to use a interface then? Seems like nobody can explain that rigth

    • @IAmTimCorey
      @IAmTimCorey  2 года назад

      I explained it in this video. You cannot inherit from multiple classes. You can apply multiple interfaces. For instance, Microsoft provides us with the IDisposable interface. If you implement it, you can use the using directive to properly dispose of your class instance. If this was a class, we would have to inherit from it. That would be a problem.

  • @WorstDeveloper
    @WorstDeveloper 2 года назад +1

    Let me tell you how to fix the sailboat problem without changing the code.
    Only rent sailboats that have an engine.

    • @IAmTimCorey
      @IAmTimCorey  2 года назад +1

      You joke, but that's how some companies do business. Change the business in order to fit the software.

  • @videojeroki
    @videojeroki 2 года назад

    What about making a class Engine and add a engine property that would be null for the sailboat or a bike

    • @IAmTimCorey
      @IAmTimCorey  2 года назад +3

      Not a great solution. Let's make that more obvious - if you had an animal class, would you want "TrunkSize" to be on all animals? That's basically what we have here. If an Engine isn't a part of all of the children, it shouldn't be in the parent.

    • @kostasgkoutis8534
      @kostasgkoutis8534 2 года назад +2

      Just to elaborate on the point above, this would force you to do null checks and create new control branches on every single a method that receives a vehicle and does something with the engine. It would lead to messy code structure, especially if you do it for many properties, like e.g. lights, windshield etc. Not what you want.

    • @videojeroki
      @videojeroki 2 года назад

      @@IAmTimCorey I hope you are not considering renting animals :P
      In any case, yes the OOP inheritance concept has to make sense, but we are suppose to program for humans so at some point decisions have to be make. Otherwise, we should all work together to make the oop model of the univers that every can use ;)

    • @videojeroki
      @videojeroki 2 года назад +1

      @@kostasgkoutis8534 good point. I also try to reduce the if else statement (2 if's max, no else per function rule ;} )

    • @kostasgkoutis8534
      @kostasgkoutis8534 2 года назад +1

      A very practical rule of thumb I personally use is that when I hit the dot and let the intellisense help me out, if I see a property or a method that just shouldn't be there, that it doesn't make sense, my class design is wrong.

  • @oligreenfield1537
    @oligreenfield1537 2 года назад

    I "never" use inheritence because I don't like to don't see what it's on my class with a quick look, so I use and abuse interfaces now with default interface implementation inheritence it's a things of the past for me

    • @IAmTimCorey
      @IAmTimCorey  2 года назад +1

      I would encourage you against saying you will never use inheritance. C# is an OOP language. Inheritance is one of its pillars. You ge the value of inheritance every time you use a class from Microsoft. There is a definite use for inheritance, you just need to make sure you don't abuse it. Not using it all is also an abuse. As for using default interfaces, that is definitely an abuse. They weren't meant to be used as inheritance. They were meant to allow you to extend an interface without breaking all of the current things that rely on that interface. Trying to use interface defaults for anything more is dangerous and will lead to problems in your code.

  • @AnotherFancyUser
    @AnotherFancyUser 2 года назад

    Did I miss it? you have a SailBoat and a boat (with engine) on your old OODemo, but not in the new one.
    You may be able to create a SeaVehicle which you can inherit to child classes like the boats, problem is, you will have the same Engine issue between boats with sails and normal boats with engines.
    How do you decouple the idea of having an engine? you cant inherit from a SeaVehicle having an Engine, do you divide by SailableSeaVehicle and SeaVehicles?

    • @IAmTimCorey
      @IAmTimCorey  2 года назад

      At that point, you are dealing with a "valid" inheritance issue and yes, you would need to create the main class without an engine because a boat can be a boat without an engine. You could create a sub-class that is called MotorBoat or something that would have the engine options in it. This, though, is where you start to see that inheritance is not really about code sharing. You need to have a reason to create this complex hierarchy so unless it really adds value, don't include the engine at all in the parent class.

    • @AnotherFancyUser
      @AnotherFancyUser 2 года назад

      ​@@IAmTimCorey Hey Tim!, thanks so much for the reply!.

    • @AnotherFancyUser
      @AnotherFancyUser 2 года назад

      @@IAmTimCorey I have a weird idea, tho it could work...
      What about we use a composition with interfaces? Something like:
      public abstract class Vehicle
      {
      protected IModeOfPropulsion _modeOfPropulsion;
      //And other common stuff about vehicles though you may want to divide still between land, sea, etc vehicles.
      }
      public class Car : Vehicle
      {
      Car(IModeOfPropulsion propulsion)
      {
      _modeOfPropulsion = propulsion
      }
      }
      public interface IModeOfPropulsion
      {
      void StartPropulsion();
      void StopPropulsion();
      }
      public class Engine : IModePropulsion
      {
      //Implementation of Interface and how it starts or stops depending of the type of the propulsion.
      }

  • @nordgaren2358
    @nordgaren2358 2 года назад

    In a few years peope are gonna be like "what are you talking about? You just press the button on your dashboard or use your phone to start your car. There's no key, silly!" 😂

    • @IAmTimCorey
      @IAmTimCorey  2 года назад +1

      True. Kind of like "dialing" a phone.

    • @nordgaren2358
      @nordgaren2358 2 года назад

      @@IAmTimCorey what do you mean? I just type in the name of the person I wanna call! What is this dialing you speak of? Cave man technology! 😂
      Ty for the video, again, Tim! I started programming with C# a year ago, and now I write and run assembly code from WPF apps. Never thought programming would be this fun!

  • @thawzan7370
    @thawzan7370 Год назад

    then what is the point of using an interface if the whole code works without inheriting the interface

    • @IAmTimCorey
      @IAmTimCorey  Год назад

      Interfaces provide a lot of benefits. For instance, here are two big ones: 1 - replacement of dependencies. For instance, Microsoft has set up all .NET web projects to have a built in logger. However, you will almost certainly want to replace it with a "real" logger at some point. You can do that by just adding your logger in Program.cs. You don't need to change any code, since all of the code uses an instance of ILogger from dependency injection. 2 - you can more easily unit test projects. If you have a method that writes to the database, you don't want it to actually write to the database. You need to mock the database connection. That is very easy if you are using dependency injection with interfaces. You just create your own implementation of the data access interface that doesn't actually write to the database.
      A bonus would be that you can do work on a class you don't know about. For instance, Microsoft provides the IDisposable interface. You can use a using statement to properly dispose of a class if it implements that interface. You can implement that in your own class and it will work with Microsoft's code.

  • @pigeonfigther
    @pigeonfigther 2 года назад +1

    Boss - You'll never believe it we just acquired a steam engine! 🙄🙄

    • @IAmTimCorey
      @IAmTimCorey  2 года назад

      Huh?

    • @pigeonfigther
      @pigeonfigther 2 года назад

      @@IAmTimCorey it was a great video, I was just making a joke about refactoring designs, and that the point is you never see it coming! Therefore it seems like concrete hierarchies will never have a long life span in an environment with that many unknowns.

  • @MuharremGorkem
    @MuharremGorkem 2 года назад

    I noticed that as years passes I use inheritance less and les. It is as if "inheritance should only be used in class libraries by class library developers" except in rare cases where keeping the natural clear-cut correspondence between entities in is-a relation in a domain and related design/implementation representation (i.e. classes with inheritance) feels so comfortable. Even in those cases, if I don't feel that mysterious comfort during implementation, I immediately give up inheritance.
    I favor use of interface more and more. Even within the same module...If a class, for instance, needs a lot of helpers for its functionality in the form of parent classes or subobjects or delegates etc, then it is best to have it one or more interfaces even for internal usage by its very close friends.