OOP (course 3): Inheritance, Abstract Classes, Interfaces and other amazing things

Buy Access

Things are about to get crazy.

You've learned the basics (Course 1). Heck, you even mastered service objects, model objects and service containers in Course 2!

Now we're getting into the meat of OO:

  • Class inheritance!
  • What about abstract classes?
  • Introducing the "protected" visibility
  • What is an interface? How can I leverage them?

This stuff will start to separate you from a beginner OO developer to someone who can really understand and flex OO code. It's hard stuff. So let's get started.


Your Guides

Ryan Weaver Leanna Pelham

Questions? Conversation?

  • 2017-09-11 Milan Vlach

    BTW, sorry for my Eng, I am really super tired today and didn't read it after myself, but I see mess I just wrote. :) (edited)

  • 2017-09-11 weaverryan

    Ha, very interesting about GO! Really cool stuff :)

  • 2017-09-11 Milan Vlach

    Yo weaverryan

    Very true, mate :)

    I would just add to (1): If you develop in other language than PHP (e.g. Golang) - there is no such a thing as an asbtract class, so you are ... kind of forced to use composition only.

    Some good references are:
    http://relistan.com/writing...

    THIS is one of the best! It describes an application architecture (AKA which layers application consists of, where to use Interface, Dependency injection; etc... ):
    https://appliedgo.net/di/

    Basically when you are writing a component in your application and feel like it can be exchanged, OR if it will be exchanged for another component, that's the first sign you should use Interface.

    Good example is the Repository. We are writing Repository for BoltDB in our Golang application. My collegues asked me if we will write a method `store model into database` for each repository. I responded like - Hey this is a perfect moment to use Interface, because we know which functions we will need in Repository layer. So we wrote a

    // Go variable declaration in Go goes like: <name> <type>
    `DatabaseInterface{
    Store(model interface{}), // Store model into database
    Get(id, type string), // Get model from database
    //blabla (writing from top of my mind)
    }`

    This way we secured that our repository is expecting an object which will consinst of methods declared inside `DatabaseInterface` :)

    Cheers :)

  • 2017-09-11 weaverryan

    Yo Milan Vlach!

    Haha, love this! Especially:

    > I've got my own life, so we'll be just friends, ok?

    Very good tip with (1): using composition over using abstract classes. We do finally talk about composition at the end of the next tutorial: https://knpuniversity.com/s.... If you're reading this and aren't sure, don't worry too much: abstract classes are great and very useful. But then someday (especially if you are writing unit tests) you may find that abstract classes have some limitations, and inheritance becomes an even better option. Basically... this is what you are saying with tip (3) I think :).

    About (2), I do (subjectively) warn users against creating their own interfaces unnecessarily in their own code.

    > Imagine your application as a Lego -> You can pick whatever piece you want (e.g. The blue one) and when you dislike it, just pick the other (the red one) and the application still works perfectly!

    This is SO true! But just make sure that you have a use-case for needing to change from the blue lego to the red lego. If you don't, creating your own interfaces adds a layer of abstraction... which means "misdirection"... which can be a bummer if you don't need it. Not having unnecessary interfaces can make your code easier to trace through.

    Thanks for the real-world tips!

    Cheers!

  • 2017-09-08 Milan Vlach

    Hello Guys,

    Again, an awesome journey :) Just wanted to add some of my experiences from life:

    1. Try to use Abstract classes ONLY when you need them, because when it comes to UnitTesting a funcionality, you need to test all of funcionality from those extended classes (all methods). Insted of doing that, you can use something called "composition over inheritance" pattern, which says: "I've got my own life, so we'll be just friends, ok? " - that means: pass required state through a __construct method (as Interface) and set its attribute, so you can use ALL of its funcionality (MUHAHAHA, I can speak with other girls now!). Two of them acts now as friends and because you use an Interface, you can pass there whatever you want and both of them are tested already! (and you are still the Dependency Injector master).

    2. Your application should have a lot of little interfaces. Imagine your application as a Lego -> You can pick whatever piece you want (e.g. The blue one) and when you dislike it, just pick the other (the red one) and the application still works perfectly!

    3. There are some cases when you feel like an Abstract class is better way - and it's perfectly ok! Just create your own rules, but all of the time `Keep It Simple`.

  • 2016-11-20 weaverryan

    Ok, all the challenges should be working again. Thanks for letting us know, and sorry for issues!

    Cheers!

  • 2016-11-20 weaverryan

    Hey Volodymyr Vadiasov!

    Ah, sorry about the issues! You're right - I can see some challenges failing to boot, that sucks! I'm working on it now - it doesn't affect all challenges, but may affect several of them. I'll update when things are smooth again.

    Cheers!

  • 2016-11-20 Volodymyr Vadiasov

    Hello,

    Challenge 1 is not working (1-4 lessons).

  • 2016-06-20 Victor Bocharsky

    Yes, it's a very cool to have strong knowledges about OOP in PHP. There're a lot of CMS, frameworks and simply well designed libraries are exist for today which are written using OOP.

  • 2016-06-20 Klemens

    As I studied informatics the world lives without OOP. Lateron coincidentally I didnt need it - but now (in times of Drupal 8) I'm very happy that with your guides I can "update" my knowlegde on a very convenient way ! Thanks a lot !

  • 2016-02-20 Syed

    Hey! If you're interested I decided to do just that. I've used the screencast as a foundation to learn stuff like composer and unit testing. https://github.com/sjhuda/k.... The master branch contain what I have so far. I'm still wet behind the ears when it comes to OOP so I'm happy to take on any suggestions.

    You'll see my composer.json has an autoload section with the namespace of the classes and the folder it lives in. In bootstrap.php I'm now just including composer's autoload.php (and db settings - but i'm going to move that into a .env file and hopefully do away with bootstrap.php). I had to go round each class and a namespace and look for any place I've used a class and include it at the top.

    I loved this series and I think the project is a great foundation to build up our php skills. Up next - unit testing!

  • 2015-12-15 weaverryan

    Thanks Neal!

    Ah yes: we'll create either an episode 4 for OO and include it... or maybe put it in its own mini-episode. It's not something you need to practically take care of anymore due to Composer (of course, as long as you know how to configure it), but it's still a fascinating topic and something good to know!

    Cheers!

  • 2015-12-15 Neal Ostrander

    Great Tutorials as always. Just wondering if at some point your going to update this one to show how to implement the autoloader for classes it is mentioned through out the videos but never implemented. Thanks

  • 2015-11-25 Hans Nieuwenhuis

    Hi,
    Just want to give You a BIG compliment on these tutorials.
    Really learned a lot and had a lot of fun !!

    Regards,
    Hans

  • 2015-10-24 weaverryan

    You're right - we talk about a lot of great things in this tutorial, but we're saving traits for the future. I've removed "traits" from the description for this tutorial

    Cheers!

  • 2015-10-23 A Maria

    Hmm, I don't see anything about traits here. Unless I'm missing something.