Python基础|类方法的强制重写与禁止重写

在Python中,类的继承与函数的重写,是我们再熟悉不过的知识点。但如何实现,方法的强制重写与禁止重写,这大概是很多初学者的一个知识盲区吧?

01强制重写

**需求:**父类一个方法,强制子类去重写。

实现的方法大约有这两种:

1、把父类变为抽象基类,然后给指定方法加上装饰器@abc.abstractmethod
2、指定方法抛出NotImplementedError异常

先来说说第一种

由于定义抽象基类,Py2和Py3有所区别,这里都举个例。

Python2.x中

# coding:utf-8
import abc

class Animal(object):
    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    def speak(self):
        pass

class Dog(Animal):
    def speak(self):
        print("汪汪...")

class Cat(Animal):
    pass

if __name__ == '__main__':
    dog = Dog()
    dog.speak()
    cat = Cat()
    cat.speak() 

输出结果

汪汪...
Traceback (most recent call last):
  File "F:/Python Script/hello.py", line 116, in <module>
    cat = Cat()
TypeError: Can't instantiate abstract class Cat with abstract methods speak

如果是Python3.x中,只需把 Animal 类改成如下即可

class Animal(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def speak(self):
        pass

输出结果,报错。

Traceback (most recent call last):
汪汪...
  File "F:/Python Script/hello.py", line 114, in <module>
    cat = Cat()
TypeError: Can't instantiate abstract class Cat with abstract methods speak

以上说明,只要把一个方法定义成抽象方法,那解释器就会要求子类,必须实现(重写)这个方法,否则就会报TypeError异常。

要注意的是,这个异常在实例化时,就会抛出,而不需要等到调用函数。

再来说说,第二种方法

我们给父类的speak方法,加上抛出异常语句。他会帮我们检测,这个方法在子类中有没有被重新实现,没有的话,就会抛出异常。

class Animal():
    def speak(self):
        raise NotImplemented

class Dog(Animal):
    def speak(self):
        print("汪汪...")

class Cat(Animal):
    pass

if __name__ == '__main__':
    dog = Dog()
    dog.speak()
    cat = Cat()
    cat.speak()

运行后,报错,提示我们这个方法没有被重写。

汪汪...
Traceback (most recent call last):
  File "F:/Python Script/hello.py", line 114, in <module>
    cat.speak()
  File "F:/Python Script/hello.py", line 101, in speak
    raise NotImplemented
TypeError: exceptions must derive from BaseException

要注意的是,这个异常只有在调用speak函数时,才会抛出。

02禁止重写

其实这个说法并不太准确。实际是可以重写的,只是无法生效而已。

来看下这个常规的例子。

class Base:
    def go(self):
        print("base")

    def run(self):
        self.go()

class Extend(Base):
    def go(self):
        print("extend")

person = Extend()
person.run()

输出结果,很正常,和我们的预期符合。

extend

先不要开心太早,来看看下面这个例子

class Base:
    def __go(self):
        print("base")

    def run(self):
        self.__go()

class Extend(Base):
    def __go(self):
        print("extend")

person = Extend()
person.run()

输出如下,你一定很纳闷,为什么会这样。

base

仔细观察一下,其实区别只有,一个是公开函数,一个私有函数。

于此,我们可以得出结论。

私有函数的作用范围仅在当前类,其表象上可以被重写,但实际上并无重写的效果。

如果你想学习自动化测试、性能测试、测试开发,但是自己又非常的迷茫,没有思路又怕耽误时间,那么你可以找我。我非常愿意将自己从业10年的经验传授给你,也愿意将自己独家的核心教程免费赠送。

公众号【程序员阿沐】找到我!我一直在等着你!

你可能感兴趣的:(Python,python,编程语言,类)