Abstract classes

Unit: 7 of 18

In the previous lessons we familiarized ourselves in detail with classes, objects and fields and their methods, as well as with their principles. In this lesson we build directly on what we learned about classes and objects so that we can take our concept of object-oriented programming to a higher level of abstraction and add some new possibilities in the form of abstract classes.

What are abstract classes?

Earlier we said that we can present abstract classes as templates that will be useful for later creation of other templates. Basically, this would mean that our abstract class is one level above the regular class and can be the beginning of a class or more classes that inherit it (the abstract class).

Here, as everywhere, the question arises – why do we actually need it and can we do without abstract classes? The short answer would always be that in the object-oriented approach we can do without abstract classes and without most other concepts (it is enough to have a regular class and its objects), however, if we want our website or application to be of high quality, with easy maintenance, without repeating the code, to know and understand more clearly why there is a method in the class, in this case we introduce the concepts such as the abstract class and other concepts that we have already mentioned and that we will learn in the following lessons.

The most practical purpose of an abstract class is to use it, namely to define in it all the abstract methods with possible input parameters, thus preparing for the creation of a regular class. Although it seems like an unnecessary step, here we will make our work easier in the first place, because we will not deal with the implementation right away, but only with what we want our regular class to do later. Let’s see an example of what the simplest way would look like to use an abstract class and later generate a regular class from it.

1
2
3
4
5
6
7
<?php
class iKorisnik{
    public function login($username, $password);
    public function register($username, $email, $password);
}

Also, the concept of polymorphism, which we have already encountered, is at work here, where an abstract class can be inherited by several different regular classes. Since in the abstract class we do not have a concrete implementation of any method, but only the definition of the essence, in the classes that inherit the abstract class we will concretely define the implementation of the essence, i.e. different forms of a single method.

Let’s see an example here. We have an abstract class IUser, in which we have a method defined for the user, of course without implementation. This login() method implies that the user will login to the system somehow, but we haven’t defined how.

After that, we will create a User class and an Administrator class in which we will implement the login() method in the modes corresponding to the User and Administrator classes, then we will instantiate one object each and analyze the results of this.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<?php
abstract class iUser{
    public abstract function login($username, $password);
}
class Administrator extends iUser{
    public function login($username, $password){
        $status_from_db = "2";
        if($username == "administrator" && $password == "HeavyPass19!"){
            if($status_from_db == "2"){
                return "Administrator is logged in!";
            }
        }
    }
}
class User extends iUser{
    public function login($username, $password){
        $status_from_db = "1";
        if($username == "user" && $password == "EasyPass!"){
            if($status_from_db == "1"){
                return "User is logged in!";
            }
        }
    }
}
$administrator = new Administrator();
echo $administrator->login("administrator", "HeavyPass19!");
echo "<br>";
$user = new User();
echo $user->login("user", "EasyPass!");

Also, it’s important to say here that when a regular class inherits from an abstract class, we actually force the regular class to implement all the methods found in the abstract class, at least by reference, without any internal logic. This is perhaps the most important part related to what I already said – an abstract class is a template for creating regular classes (templates). Just as a class forces an object to have methods and fields defined in the class, so an abstract class forces, through inheritance, the regular class to find certain methods in it and implement them, at least in the most basic way.

Here we will look at an example of what different implementations of the methods we inherited from an abstract class look like in a regular class. It is important to see what the basic implementation is, that is, the one that this type of inheritance requires to the smallest extent possible, but also to see what the concrete implementation with internal logic is.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
<?php
abstract class iUser{
    public abstract function login($username, $password);
}
class Administrator extends iUser{
    public function login($username, $password){
        $status_from_db = "2";
        if($username == "administrator" && $password == "HeavyPass19!"){
            if($status_from_db == "2"){
                return "Administrator is logged in!";
            }
        }
    }
}
class User extends iUser{
    public function login($username, $password){
        $status_from_db = "1";
        if($username == "user" && $password == "EasyPass!"){
            if($status_from_db == "1"){
                return "User is logged in!";
            }
        }
    }
}
class DifferentUser extends iUser{
    public function login($username, $password){
        // This works even with this wrong logic!
        return "User is logged in!";
    }
}
class OtherUser extends iUser{
    public function login($username, $password){
        // This is not wrong, even if body is empty!
    }
}
$administrator = new Administrator();
echo $administrator->login("administrator", "HeavyPass19!");
echo "<br>";
$user = new User();
echo $user->login("user", "EasyPass!");
echo "<br>";
$different_user = new DifferentUser();
echo $different_user->login("user", "EasyPass!");
echo "<br>";
$other_user = new OtherUser();
echo $other_user->login("user", "EasyPass!");

Finally, we will mention some more rules and repeat the existing ones that we need to understand while working with abstract classes.

  • An abstract class is a class that has at least one abstract method.
  • Abstract methods are methods that are declared (defined) but not implemented.
  • An abstract class can have regular methods with an implementation, although this is generally not the case due to usage.
  • When a regular class inherits an abstract class, it must create in it all methods that are marked as abstract methods within the abstract class.
  • When we implement methods, it’s important that the access modifier is of the same level or a lower level (for example, we can’t go from public to private, only the other way around).
  • When we implement methods, the number of arguments (parameters) must be the same as in the abstract method, with the fact that we can add optional parameters.

With this we learned what an abstract class is and how it can be useful in object-oriented programming. In the following lessons we will familiarize ourselves, among other things, with interfaces and traits, which will raise our object-oriented approach to an even higher level of abstraction.

Exercise 07.01

Similar to the previous exercise (06.01), you need to create an abstract class for laptops.

In that class you have to define everything that every generic laptop has: manufacturer, model, price.

You will also need to declare the abstract info method.

After that, you’ll need to create two specific classes (for example, the MicrosoftLaptop and AppleLaptop classes).

In those classes, you should inherit the generic laptop class and define some details for these two classes.

For example, Microsoft Surface laptops have a touch screen, while Apple laptops have a touch bar.

Instantiate these classes and list all the information you have about them.

Of course, you should use both the constructor and the list (print) method.

Note: The example of the solution to this exercise can be seen in the repository of this course or at the link below:

https://github.com/amarbeslija/php-development

 

An abstract class is one that:

Leave a Reply

Your email address will not be published. Required fields are marked *