Everything we have coded up until now revolves around functions (i.e. blocks of statements which manipulate data). This is called the procedure-oriented way of programming. There is another way of organizing your code, which is to combine data and functionality, and wrap it inside something called an object. This way of coding its called the object-oriented way of programming, and is ideal when writing large applications.
The universe is made of different objects like: the sun, earth, moon, chairs and crazy people. Similarly, we can imagine that our car is made up of different objects, like: steering wheel, air conditioner, engine etc. In that same way, there are object oriented programming concepts which assume that everything is an object, and implements a software for different objects.
There are two kinds of people in this world:
The 2 biggest advantages are:
Creating a program in an object-oriented way can be slower at the beginning because you have to divide all of your code into all of these little parts. Also, there are certain – very particular – scenarios when using this practice can complicate your program.
But hey!!…you don’t need to be one of those people that must "love" or "hate" everything. Instead, try to understand that everything has pros and cons. Become a master in this technique and use it wisely.
Classes and objects are the two main aspects of object oriented programming. A class creates a new type (of object) where objects are particular instances of a particular class.
Let’s say you have a new car with licence plate XHR-ABM. That specific object will be the instance of an object with the car class.
Every application and website that you are going to build needs to have its own set of classes. Which classes will depend on the business logic behind the website (it’s ultimately all about the client and the need(s) that they are trying to resolve).
For example: A Person class has: skin color, race, name, social-security number, etc. All properties have a data-type, like: Integer, String, Float, Null, Arrays.
If we want to store the birth-date of the person using simple data-types we will have to define 3 properties: yearBirthDate, monthBirthDate and dayBirthDate.
Some properties are calculated during runtime every time we need them. For example: age. The problem with age is that it changes over time. That is why it is not a good idea to store the current age of the user. Instead, it is better to declare a calculated property called "Age," and declare a function that calculates the current age of the user based on its birthDate.
Lets do our first Class-Diagram! Let say that you are designing the object oriented model of a new website, and your client wants to create a shopping cart. This is easy because these types of websites are being made every day (it will actually be both wiser and more efficient to clone an already-made model; however, for the sake of this lesson, we are going to continue with our example).
When building any Class Diagram of your application, you should take these following bullets into consideration:
☝It is important to say that there are no right or wrong solutions for these kinds of problems. You must remain confident and stick to your strategy. However, make sure you take enough time to design a good one before adding some code – otherwise it will become difficult to change things up during the development of big applications (with lots of classes) .
We have a client that wants to start selling cars on the internet. What do we do? The website will probably need to have an index page with a list of all the cars that he has available at the moment. The user will be able to add cars to a shopping cart and finish the order whenever it is ready.
Okay, it is obvious that the first objects we need are a ShoppingCart class and a Car class.
Now that we have our first 2 classes of objects, to continue developing the model you can can ask yourself (or the client) the following:
Class diagrams also need to express the way classes relate to each other and the functions they have (including "getter" and "setter" functions).
To declare a class we need to use the word "class" anywhere in our code followed by the class name that we want to assign to it. Start and finish each class with brackets.
The properties are declared at the beginning of each class; globally within the brackets of that particular class.
Right after the properties, you have to declare the functions.
The Class Constructor The "class constructor" is the first function that gets called in the entire class. It gets called as soon as the object is created. It is very good practice to assign initial values to the class properties inside its constructor method.
We call the constructor one of the "magic functions." They are "magical" because you don’t have to call those functions yourself – they are magically called by the server depending on they purpose that they have (in the case of the constructor, remember the purpose is about initialization).
Magic functions always start with two underscores, and the __construct() . We use __construct() in order to do something as soon as we create an object out of a class. A function of this kind is called a constructor. Usually we use the constructor to set a value to a property.
The properties are declared at the beginning of each class (globally within the brackets of that particular class). Right after the properties, you have to declare the calculated properties as well.
All class properties have a Public visibility by default; you can change their visibility to private if you think it best:*
Properties that can be accessed from outside the class using the -> operator.
They cannot be accessed from outside the class; the only way to access or use them is inside the class functions using the $this-> operator. To access a private property you need to create two functions: a getter and a setter:
Perhaps you may feel that there it is pointless to use "getters" and "setters" for every property, and you are probably right in most cases. But, even if you think that writing the "getters" and "setters" are NOT necessary for a particular property, it is a very good practice because you never know when you will need them.
When do we really need Private Properties and a "getter/setter"?
When we want to validate data: Let’s say we want to validate that a person’s name cannot contain numbers – a setter is great because you can avoid assigning the value if it is not how you like it.
Some properties need to be set internally: For example: an automatically generated ID that you don’t want the user to be able to set, but you do want the user to get.
Here is another example of a "getter/setter" in real-life:
☝Some languages, like PHP, have their own __get and __set magic functions to implement getters and setters. However, this is not a good idea because of performance issues. It is a better idea to create your own "get/set" functions according to your project needs. Here is the reasoning behind it.
Encapsulation is the process of combining data and functions into a single unit called a "class."
When you create an object in an object-oriented language, you can hide the complexity of the internal workings of the object. As a developer, there are two main reasons why you would choose to hide complexity:
The first reason is to provide a simplified and understandable way to use your object without the need to understand the complexity inside of it.
For example, a car driver doesn’t need to know how an internal combustion engine works. It is sufficient to know how to start the car, how to engage the transmission (if you want to move), how to provide fuel, how to stop the car, and how to turn off the engine. You know how to use the key, the shifter (and possibly clutch), the gas pedal and the brake pedal to accomplish each of these operations. These basic operations form an interface for the car. Think of an interface as the collection of things you can do to the car without knowing how each of those things works.
Hiding the complexity of the car from the user allows anyone, not just a mechanic, to drive a car. In the same way, hiding the complex functionality of your object from the user allows ANYONE to use it and to find ways to reuse it in the future (regardless of their knowledge of the internal workings). This concept of keeping implementation details hidden from the rest of the system is key to object-oriented design.
In object-oriented programming, inheritance is the concept that when a class of objects is defined, any subclass that is defined can inherit the definitions of one or more general classes. This means that, for the programmer, an object in a subclass need not carry its own definition of data and methods that are generic to the class (or classes) of which it is a part. This not only speeds up program development; it also ensures an inherent validity to the defined subclass object (what works and is consistent about the class will also work for the subclass).
"Car" is a classification of "Four-Wheeler." Here, "Car" acquires the properties of a "Four-Wheeler." Other classifications could be a Jeep, Tempo, van etc. "Four-Wheeler" defines a class of vehicles that has four wheels, a specific range of engine power, load carrying capacity etc. "Car" (termed as a sub-class) acquires these properties from "Four-Wheeler" (termed as a super-class), and has SOME specific properties that are different from other classifications of "Four Wheeler," such as luxury, comfort, shape, size, usage, etc.
"Car" can have further classification such as "Open Car," "Small Car," "Large Car," etc, which will acquire the properties from BOTH "Four-Wheeler" AND "Car" – but will still have some specific properties. This way the level of hierarchy can be extended to any level.