PHP - Encapsulation & Abstraction - Full PHP 8 Tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] we are slowly but surely advancing into more fun interesting and advanced topics with basics out of the way let's talk about the four principles of object-oriented programming which are encapsulation obstruction inheritance and polymorphism in this video we'll cover encapsulation and abstraction and in the next video we'll talk about the inheritance and polymorphism so what is encapsulation encapsulation simply bundles the data and methods that operate on that data within one unit like a class for example it hides the internal representation or the state of the object which protects the integrity of that object encapsulation ensures that your object manages its own state and nothing can change that unless it's explicitly allowed let's take this transaction class as an example here i have a single property called the amount which is currently set to public and as you know we have three visibility access modifiers public private and protected public simply means that the property or the method is accessible outside of this class by anyone interacting with the object private means that the property and method can only be accessed from within the class itself and protected is pretty much the same thing as the private but it extends to the child or the subclasses which we'll cover once we get to the inheritance so don't worry about that for now setting properties to public like this can break the encapsulation principle because anyone interacting with this object outside of the class can now modify the state of our object which could result in nasty bugs to show you this in action let's switch over to the index.php here where i'm creating the transaction object and we're passing the 25 as the argument which then gets set to the amount property and then we have the process method here which simply prints processing amount transaction so let's call this method from the index.php so i'm going to go here and simply do transaction process and we refresh the page and everything seems to work right it says that we're processing 25 transaction but because the amount property is set to public we're able to change the state of our object by simply changing the amount property to something like 125. now if we refresh the page we see that now it says that it's processing 125 transaction which is a problem right we've passed the 25 in the constructor and then we're allowed to explicitly override that and change the amount properly which directly affects how the process method is handled and even though this might look harmless to you now and you might be thinking that yeah i would never do this i would never pass a 25 here and then right after change it to 125 but you cannot guarantee that when you're working in teams also think about it in a different way what if the transaction object was given to you in a method so let's say you were inside a method and it accepts an argument where this transaction object is passed to you and then if you have ability to override and change the amount within that class without you even knowing what the original amount is because you're not the one creating the transaction object you're simply the one accepting the transaction object through the method because the code allows you to do something like this you might actually do that whether it's intentional or accident and something somewhere in your code will blow up we can fix this by setting our property to private which will ensure that interaction outside of this class will be restricted but now you might be asking what if you want to access the amount property outside of the class in that case you're able to introduce a public method which is also called the getter method also known as the accessor to retrieve the value of the property so you could have something like public function getamount and this simply returns amount if you wanted to change the amount for whatever reason then you could introduce another public method called set amount which is called the setter to update the amount property so we could do set amount and simply set this amount to the amount that will accept as an argument and now we have the getter and setter methods but wait a second if we're going to expose the getter and setter method for every property that we have isn't that pretty much the same thing as just having this property as public because right now we have the amount property set to private but we are exposing these two public methods here which gets the property value and another one mutates the property value which essentially changes the state of the transaction so i could essentially go back to index.php and instead of now trying to do this which would result in error right if i refresh the page we get the fatal error because this property is set to private we could now do set amount and we're back to the same problem where we've passed 25 as the constructor value and we're able to change the state of our object and change the amount of the transaction that we're processing getters and setters might be used to introduce encapsulation to the class but they can actually cause more harm than good by breaking the encapsulation principle and because of this you might hear a lot about having getters and setters being the best practice i'm not going to tell you whether it's good or bad or whether you should use it or you should not use it i'm going to leave that up to you to decide but the way i go about this is that if i have a property that represents the state of the object i make it private and i make sure that i don't have another method that changes that state of the object instead i accept the value through the constructor or through the method that we call instead of the setter so in this case i would simply remove the set amount and we're already accepting the amount in the constructor and we're setting it there and if for whatever reason we needed to change the amount then we should simply just create a new transaction object instead of changing the state of this object if we wanted to process a 125 transaction then we shouldn't be mutating and changing this object we should be processing a different transaction right and about the getter method here which gets the amount property i would simply leave that in if i need to access the amount but if i don't really need to access the amount i'm not going to leave that in just because i have the amount property and maybe down the road i might need to access the amount property so i'm going to remove that for now because we don't need it and let's change this back to being passed in the constructor and let's move on there are cases of course where the getters and setters make sense in some cases you might have some additional logic that you perform before you set the property or before you get the property like some validation or formatting for example and so on in those cases then setters and getters do make sense also with setters you can do method chaining where you kind of build up your object by calling bunch of methods which gives you this fluent interface and you'll see that as a common practice in some cases it's also perfectly fine to have public properties and you'll see them be used in popular frameworks so there are definitely some use cases for them one use case is for the data transfer objects or in short dtos which we'll cover later in this course as well my advice here would be to not define getter and setter methods for every single property unless and until you actually need them the point is don't just create setters and getters just because you have a property in addition to protecting your properties you might also have some methods that are not meant to be exposed or publicly available they might be internal implementation so you would want to hide those as well so for example within the process method we might be calling some other methods right we might be calling something like generate receipt which maybe just generates the receipt of the transaction and then maybe we have a method that sends the email now we can create these methods here just to demonstrate but these methods are internal implementations and they should not be set to public if you set this to public that means that this method can be called without ever calling process outside of this class which can cause some issues right you might be generating some receipt here or if you set this to public as well you might be sending an email before actually generating the transaction and so on that's why because these are internal implementations you would want to set these to either private or protected and we'll talk about the protectedly in the later lesson but you would want to restrict direct access or public access to these methods and speaking of restricting access to private and protected properties and methods i want to show you a quick trick on how you could actually break the encapsulation and access private and protected properties and methods while it is true that it will throw a fatal error if you try to access restricted properties and methods you can actually still get the access to those restricted properties and methods through something called php's reflection api so for example if i go over to index.php and try to access amount property which is private i would get the fatal error right so let's now try to access this private property using the reflection api and we'll cover the reflection api in more detail later in the course just bear with me here reflection api basically just adds the ability to introspect your classes so we could do something like reflection property equals new reflection property and the first argument we pass the fully qualified class name transaction class and the second argument is the property name and in this case that's amount and now we can simply do reflection property set accessible to true now this does not make this amount properly directly accessible on the transaction object we'll still get the fatal error but now we can do something like this let's vary dump reflection property get value and we pass the object on which we're getting that value and that is transaction object let's refresh the page and as you can see we have accessed the private property amount and it's printing 25 right here now if we can access the private property can we modify that private property the answer is yes we can do something like this reflection property set value and we pass the transaction object as the first argument and second argument would be the actual amount so that's 125. if i refresh the page we have changed the 25 which was the original amount to 125. so as you can see we're not really restricting anything by setting properties and methods to private or protected but the point of private and protected access modifiers is to let the one know interacting with the object that certain properties and methods are meant to be kept private or protected they are internal implementations and they are meant to be used within that class don't worry too much about this because in most cases it would not matter i just wanted to share this trick with you to show you how you could actually access private and protected properties and methods you probably wouldn't actually do this in a real application all right so let's remove this and let's move on to obstruction there are different ways to interpret the term obstruction and some refer to obstruction as abstract classes and methods but the obstruction principle from the four principles of object-oriented programming refers to a different concept and is not the same as abstract classes and methods yes you could implement obstruction using abstract classes and methods but it's not the same thing obstruction is actually closer and goes hand in hand with encapsulation instead of abstract classes and methods we'll cover abstract classes and methods later but obstruction simply means that internal implementation details of an object are hidden from the user you could call a method on the object maybe provide some input and maybe get an output but you don't care how the method is actually implemented and how it works behind the scenes all you care about is that you just call it and you expect some kind of output or some kind of result for example when we call the process method here we don't care what goes on behind the scenes we don't care what payment gateway this process method connects to we don't care how it's saved in the database we don't care whether it sends an email or not and we don't care how it generates the receipt all we care about is that we process the transaction this is what obstruction is in simple terms you're basically hiding the implementation details from the user you could change the way transaction is processed maybe you could change the payment gateway or maybe you now decide that you don't want to send the email here or something like that or maybe you change the way the receipt is generated and so on the point is that the place where you call the process method does not and should not care what goes on within that process method and any changes to that process method should not affect this part of the code here setting properties to public breaks the encapsulation as we mentioned before right but if you set this to public it also breaks the abstraction because for example we have this amount property set to public and we have used this amount property in maybe 100 other places in our code base let's say that later we decided that we wanted to change the type of this property to something like integer because maybe we're now expecting it in cents instead of in dollars or something or maybe you changed it into string or whatever basically you made some kind of change in the definition of this property now your code will blow up in 100 different places or you will have some unexpected results because you're directly accessing this property so basically if you try to build your classes in a way that does not break encapsulation and does not break obstruction you will be on track on achieving a good object-oriented design there is a question that you could ask yourself when building your classes can you make changes to this class without breaking too many things outside of this class if the answer is yes then you have a well-designed class and maintaining and extending that code base and that class will be much easier so what's the difference between encapsulation and obstruction because they have some things in common right we are working with the public and private properties here we've talked about that setting public breaks the encapsulation but now it also breaks the obstruction and so on right so the encapsulation hides the internal state or the information while the obstruction hides the actual implementation of it i know i said a lot and don't worry if something sound a bit confusing and some things don't make sense take your time and watch this video as many times as needed also as i mentioned before there are certainly some use cases for public properties and setters and getters just keep encapsulation and abstraction principles in mind when designing and building out your classes before we wrap up this video i want to show you one last thing as a bonus in this lesson did you know that objects of the same type can actually access each other's private and protected properties and methods for example if we had a method here something like copy from and we accepted a transaction object because the type of the argument is transaction and is the same as the current object which is the calling object which is the this variable right so we are in the same object and the types match you're actually able to access private and protected properties and methods of that object so we could do something like vardom transaction amount and transaction send email and even though send email doesn't return anything we can simply just return true for now and let's call copy from here transaction copy from and let's create a new transaction and pass hundred as the amount and let's comment out the process from here and it's refresh and as you can see it prints hundred and it prints true which means that we're able to access the private and protected properties and methods of that object this is it for this video thank you so much for watching we'll talk about inheritance and polymorphism in the next video please hit like button if you enjoyed this lesson share and subscribe and i'll see you next time
Info
Channel: Program With Gio
Views: 3,130
Rating: undefined out of 5
Keywords: advanced php course, learn php the right way, object oriented php, php, php course, php in 2021, php tutorial, php oop tutorial for beginners full, php8, oop principles, object oriented programming principles, encapsulation, abstraction, oop encapsulation, oop abstraction
Id: kA9BTNPFObo
Channel Id: undefined
Length: 15min 22sec (922 seconds)
Published: Tue Mar 30 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.