The most important concepts of object orientation are Class and Instance. Class is template, and instances are specific objects created according to classe. Each object has the same method, but their data may be different.
In Python, for example, the Employee class is defined through the class keyword.
class Employee(object): pass
Class is followed by the class name, that is Employee. The class name is usually a word that begins with a capital letter, followed by (object), which class inherits from. The concept of inheritance will be explained later.
With the Employee class defined, you can create an instance of Employee based on the Employee class, which is implemented through the class name +()
>>> tom = Employee() >>> tom <__main__.Employee object at 0x10iox08o0> >>> Employee <class '__main__.Employee'>
As you can see, the variable tom points to an instance of Employee, 0x10iox08o0 is the memory address, the address of each object is different, but Employee itself is a class.
Feel free to bind properties to an instance variable, such as a name attribute to the instance tom.
>>> tom.name = 'Tom Trump' >>> tom.name 'Tom Trump'
Because classes can act as templates, you can force some attributes that you think must be bound into the instance when you create it.
By defining a special __init__ method, the name, salary and other attributes are tied up when the instance is created:
class Employee(object): def __init__(self, name, salary): self.name = name self.salary = salary
Note: there are two underscores before and after the special method “__init__”. Notice that the first argument to the __init__ method is always self, representing the created instance itself, so inside the __init__ method, various attributes can be bound to self, since self is referring to the created instance itself.
With the __init__ method, you can’t pass in empty arguments when you create an instance, you have to pass in arguments that match the __init__ method, but self doesn’t need to pass, and the Python interpreter will pass in the instance variable itself.
>>> tom = Employee('Tom Trump', 10000) >>> tom.name 'Tom Trump' >>> tom.salary 10000
The only difference between functions defined in a class is that the first argument is always the instance variable self and, when called, it is not passed. In addition, class methods are no different from normal functions, so you can still use default arguments, variable arguments, keyword arguments, and named keyword arguments.
An important feature of object-oriented programming is data encapsulation. In the Employee class above, each instance has its own name and salary data. We can access this data through functions, such as printing an employee’s salary:
>>> def print_salary(employee): ... print('%s: %s' % (employee.name, employee.salary)) ... >>> print_salary(tom) Tom Trump: 10000
However, since the Employee instance itself owns the data, there is no need to access it from outside functions, and functions that access the data can be defined directly inside the Employee class, thus wrapping the “data”. These functions that encapsulate data are associated with the Employee class itself, which we call class methods:
class Employee(object): def __init__(self, name, salary): self.name = name self.salary = salary def print_salary(self): print('%s: %s' % (self.name, self.salary))
To define a method, it is the same as a normal function except that the first argument is self. To call a method, you simply call it directly on the instance variable, except that self is not passed, and other parameters are passed in normally.
>>> tom.print_salary() Tom Trump: 10000
In this way, if we look at the Employee class from the outside, we only need to know that the instance creation needs to give the name and salary, and how to print is defined inside the Employee class. The data and logic are “encapsulated” and easy to call without knowing the details of the internal implementation.
Another benefit of encapsulation is that you can add new methods to the Employee class, such as get_level:
class Employee(object): ... def get_level(self): if self.salary >= 10000: return 'Manager' elif self.salary >= 5000: return 'Leader' else: return 'Worker'
Similarly, the get_level method can be called directly on the instance variable without knowing the internal implementation details.