Object-Oriented Polymorphism and Inheritance for Introduction to Python

Contents of this chapter

    Python object-oriented polymorphism and inheritance comparison

=========================================

 

In OOP programming, when we define a class, we can inherit from an existing class, the new class is called a subclass (Subclass), and the inherited class is called a base class, parent class or superclass (Base class, Super class).

 

For example, we've written a class called Animal that has a run() method that prints directly:

class Animal(object):
  def run(self):
    print 'Animal is running...'

 

When we need to write Dog and Cat classes, we can inherit directly from the Animal class:

class Dog(Animal):
  pass

class Cat(Animal):
  pass

For Dog, Animal is its parent class, and for Animal, Dog is its subclass. Cat and Dog are similar.

 

What are the benefits of inheritance? The biggest benefit is that the subclass gets the full functionality of the parent class. Since Animial implements the run() method, Dog and Cat, as its subclasses, automatically have the run() method without doing anything:

dog = Dog()
dog.run()

cat = Cat()
cat.run()

The results are as follows:

Animal is running...
Animal is running...

Of course, you can also add some methods to subclasses, such as the Dog class:

class Dog(Animal):
  def run(self):
    print 'Dog is running...'
  def eat(self):
    print 'Eating meat...

The second benefit of inheritance requires us to make a little code improvement. As you can see, whether it is Dog or Cat, when they run(), they display Animal is running.... The logical approach is to display Dog is running... and Cat is running... respectively, so , the improvements to the Dog and Cat classes are as follows:

class Dog(Animal):
  def run(self):
    print 'Dog is running...'

class Cat(Animal):
  def run(self):
    print 'Cat is running...'

Run it again and the result is as follows:

Dog is running...
Cat is running...

 

When both the subclass and the superclass have the same run() method, we say that the subclass's run() overrides the superclass's run(), and when the code runs, the subclass's run() is always called . In this way, we get another benefit of inheritance: polymorphism.

 

To understand what polymorphism is, we first need to explain a little more about data types. When we define a class, we are actually defining a data type. The data types we define are no different from the data types that come with Python, such as str, list, and dict:

a = list() # a is of type list 
b = Animal() # b is of type Animal 
c = Dog() # c is of type Dog

 

To determine whether a variable is of a certain type, you can use isinstance() to determine:

>>> isinstance(a, list)
True
>>> isinstance(b, Animal)
True
>>> isinstance(c, Dog)
True

It seems that a, b, and c do correspond to the three types of list, Animal, and Dog.

But wait, try:

>>> isinstance(c, Animal)
True

But if you think about it, it makes sense, because Dog is inherited from Animal. When we create an instance c of Dog, we think that the data type of c is Dog, but it is also correct that c is also Animal. , Dog is originally a kind of Animal!

 

Therefore, in the inheritance relationship, if the data type of an instance is a subclass, its data type can also be regarded as a superclass. However, the reverse does not work:

>>> b = Animal()
>>> isinstance(b, Dog)
False

Dog can be regarded as Animal, but Animal cannot be regarded as Dog.

 

To understand the benefits of polymorphism, we need to write one more function that accepts a variable of type Animal:

def run_twice(animal):
  animal.run()
  animal.run()

 

When we pass in an instance of Animal, run_twice() prints out:

>>> run_twice(Animal())
Animal is running...
Animal is running...

When we pass in an instance of Dog, run_twice() prints out:

>>> run_twice(Dog())
Dog is running...
Dog is running...

When we pass in an instance of Cat, run_twice() prints:

>>> run_twice(Cat())
Cat is running...
Cat is running...

It doesn't seem interesting, but think about it, now, if we define another Tortoise type, also derived from Animal:

class Tortoise(Animal):
  def run(self):
    print 'Tortoise is running slowly...'

 

When we call run_twice(), we pass in an instance of Tortoise:

>>> run_twice(Tortoise())
Tortoise is running slowly...
Tortoise is running slowly...

You will find that adding a subclass of Animal does not require any modification to run_twice(). In fact, any function or method that relies on Animal as a parameter can run normally without modification. The reason is polymorphism.

 

The advantage of polymorphism is that when we need to pass in Dog, Cat, Tortoise..., we only need to receive the Animal type, because Dog, Cat, Tortoise... are all Animal types, and then operate according to the Animal type. That's it. Since the Animal type has a run() method, any incoming type, as long as it is an Animal class or a subclass, will automatically call the run() method of the actual type, which is what polymorphism means:

For a variable, we only need to know that it is of type Animal, without knowing exactly its subtype, we can safely call the run() method, and the specific call of the run() method is on Animal, Dog, Cat or Tortoise On the object, it is determined by the exact type of the object at runtime. This is the real power of polymorphism: the caller only calls, regardless of the details, and when we add a subclass of Animal, just make sure that the run() method is written correctly , regardless of how the original code was called. This is the famous "open-closed" principle:

Open to extensions: Allows to add Animal subclasses;

Closed to modification: functions such as run_twice() that depend on the Animal type do not need to be modified.

继承还可以一级一级地继承下来,就好比从爷爷到爸爸、再到儿子这样的关系。而任何类,最终都可以追溯到根类object,这些继承关系看上去就像一颗倒着的树。比如如下的继承树:

 

小结

 

继承可以把父类的所有功能都直接拿过来,这样就不必重零做起,子类只需要新增自己特有的方法,也可以把父类不适合的方法覆盖重写;

有了继承,才能有多态。在调用类实例方法的时候,尽量把变量视作父类类型,这样,所有子类类型都可以正常被接收;

Python3中,如果没有合适的类可以继承,就继承自object类。

 

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324443561&siteId=291194637