python之12 面向对象高级特性

12.1 继承
继承
继承可以使得子类具有父类的属性和方法或者重新定义、追加属性和方法等。

python中如何继承
在定义类的时候,类名后有个括号,当括号里写着另外一个类的名字时,表示该类继承于另外一个类

#定义animal类
class Person:
    def __init__(self,name):
        self.name = name
    def say(self):
        print("My name is"+" "+self.name)
#Actor继承Person
class Actor(Person):
    pass
#Student继承Person
class Student(Person):
    pass

actor1=Actor("Mew")
actor1.say()
print(actor1.name)

student1=Student("Gulf")
student1.say()
print(student1.name)
  • 子类可以有自己的属性与方法
#定义animal类
class Person:
    def __init__(self,name):
        self.name = name
    def watch(self):
        print(self.name+" "+"is watching TV")
#Actor继承Person
class Actor(Person):
    def study(self):
        print(self.name+" "+"is studying")

actor1=Actor("Mew")
actor1.watch()
actor1.study()
  • 子类具备父类所有的属性与功能,但是父类并不具备子类的属性与功能
#定义animal类
class Person:
    def __init__(self,name):
        self.name = name
    def watch(self):
        print(self.name+" "+"is watching TV")
#Actor继承Person
class Actor(Person):
    def study(self):
        print(self.name+" "+"is studying")

person=Person("people")
actor=Actor("Mew")
print(isinstance(person,Actor))#验证person是否是Actor的实例 False
print(isinstance(actor,Person))#验证actor是否是Person的实例 True
  • 当子类有自己的构造方法时,将会覆盖父类的构造方法
#定义animal类
class Person:
    def __init__(self):
        print("person")
#Actor继承Person
class Actor(Person):
    def __init__(self):
        print("Gulf")
actor=Actor()
#输出Gulf
  • 子类重写父类方法
#定义animal类
class Person:
    def __init__(self):
        print("person")
    def say(self):
        print("a person loves Gulf")
#Actor继承Person
class Actor(Person):
    def __init__(self):
        print("Mew")
    def say(self,name):
        print("Mew loves"+" "+name)
actor=Actor()
actor.say("Gulf")

注意: 当且仅当子类方法与父类同名,入参相同,才可称之为重写父类的方法

12.2 super的作用及其用法

#定义animal类
class Person:
    def __init__(self,name):
       self.name=name
#Actor继承Person
class Actor(Person):
    def __init__(self):
        print("actor")
actor=Actor()
print(actor.__dict__)

输出:
actor
{}

super() 函数是用于调用父类(超类)的一个方法。一般是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序(MRO)、重复调用(钻石继承)等种种问题。

super函数的基本语法

super(类名,self)

在python3中,可以直接使用super()而无需任何参数来调用父类

#定义animal类
class Person:
    def __init__(self,name):
       self.name=name
#Actor继承Person
class Actor(Person):
    def __init__(self,name):
        super(Actor,self).__init__(name)
        print("actor")
actor=Actor("Mew")
print(actor.__dict__)
print(actor.name)

输出:
actor
{‘name’: ‘Mew’}
Mew

12.3 抽象方法与多态
抽象方法:
在面向对象编程语言中抽象方法指一些只有方法声明,而没有具体方法体的方法。抽象方法一般存在于抽象类或接口中。抽象类的一个特点是它不能直接被实例化,子类要么是抽象类,要么,必须实现父类抽象类里定义的抽象方法
在python3中可以通过使用abc模块轻松的定义抽象类

定义抽象类

from abc import ABCMeta,abstractmethod
#定义抽象类时,使用metaclass=ABCMeta
class Person(metaclass=ABCMeta):
    @abstractmethod
    def say(self):
        pass
class Actor(Person):
    def say(self):
        print("I love Gulf")
actor=Actor()
actor.say()

抽象类的子类必须实现抽象类中所定义的所有方法,否则,程序不能正确运行

from abc import ABCMeta,abstractmethod
class Person(metaclass=ABCMeta):
    @abstractmethod
    def say(self):
        pass
class Actor(Person):
        pass
actor=Actor()
actor.say()

输出:
TypeError: Can’t instantiate abstract class Actor with abstract methods say

即使是实现部分抽象方法也是不行的

from abc import ABCMeta,abstractmethod
class Person(metaclass=ABCMeta):
    @abstractmethod
    def say(self):
        pass
    @abstractmethod
    def word(self):
        pass
class Actor(Person):
        def say(self):
            print("I love Gulf")
actor=Actor()
actor.say()

输出:
TypeError: Can’t instantiate abstract class Actor with abstract methods word

多态
不同的子类对象调用相同的父类方法,产生不同的执行结果,可以增加程序的灵活性和可扩展性

from abc import ABCMeta,abstractmethod
class Person(metaclass=ABCMeta):
    @abstractmethod
    def say(self):
        pass
    @abstractmethod
    def word(self):
        pass
    def inaword(self):
        self.say()
        self.word()
class Actor(Person):
    def say(self):
        print("My name is Mew")
    def word(self):
        print("And I love Gulf")
class Student(Person):
    def say(self):
        print("My name is Gulf")
    def word(self):
        print("And I love Mew")
#不同的子类对象,调用父类的inaword()方法,产生不同的执行结果
actor=Actor()
student=Student()
actor.inaword()
student.inaword()

12.4 多重继承
一个子类可以继承多个父类

class Wife:
    def wifesay(self):
        print("I am Gulf")
class Husband:
    def husband(self):
        print("I am Mew")
class Viewer(Wife,Husband):
    pass
viewer=Viewer()
viewer.wifesay()
viewer.husband()

如果父类中有相同的方法,子类会按照继承的顺序继承

class Wife:
    def wifesay(self):
        print("I am Gulf")
    def husband(self):
        print("And I am Husband")
class Husband:
    def husband(self):
        print("I am Mew")
#class Viewer(Wife,Husband):
#输出:I am Gulf And I am Husband
class Viewer(Husband,Wife):
#输出:I am Gulf  I am Mew
    pass
viewer=Viewer()
viewer.wifesay()
viewer.husband()

12.5 多重继承
新式类与旧式类
新式类都从object继承(python3中,默认都继承自object),经典类不需要。
新式类的MRO(method resolution order 基类搜索顺序)算法采用C3算法广度优先搜索,而旧式类的MRO算法是采用深度优先搜索
新式类相同父类只执行一次构造函数,经典类重复执行多次。

class Person:
    def say(self):
        print("person")
class Actor1(Person):
    def say(self):
        print("Gulf")
class Actor2(Person):
    def say(self):
        print("Mew")
class Viewer(Actor1,Actor2):
    def say(self):
        print("we love them")
v=Viewer()
v.say()

输出:
we love them

菱形继承(钻石继承)
在多重继承中,直接使用父类名字调用构造,会发生问题

class Person:
    def __init__(self):
        print("this is a person")
    def say(self):
        print("person")
class Actor1(Person):
    def __init__(self):
        Person.__init__(self)
    def say(self):
        print("Gulf")
class Actor2(Person):
    def __init__(self):
        Person.__init__(self)
    def say(self):
        print("Mew")
class Viewer(Actor1,Actor2):
    def __init__(self):
        Actor1.__init__(self)
        Actor2.__init__(self)
    def say(self):
        print("we love them")
v=Viewer()
v.say()

输出:
this is a person
this is a person
we love them

使用**super()**可以解决菱形继承多次调用构造的问题

class Person:
    def __init__(self):
        print("they are a couple")
    def say(self):
        print("person")
class Actor1(Person):
    def __init__(self):
        print("Gulf")
        super().__init__()
    def say(self):
        print("Gulf")
class Actor2(Person):
    def __init__(self):
        print("Mew")
        super().__init__()
    def say(self):
        print("Mew")
class Viewer(Actor1,Actor2):
    def __init__(self):
        super().__init__()
    def say(self):
        print("we love them")
v=Viewer()
v.say()

输出:
Gulf
Mew
they are a couple
we love them

12.6 枚举类
一个集的枚举是列出某些有穷序列集的所有成员的程序,或者是一种特定类型对象的计数。这两种类型经常(但不总是)重叠。

from enum import Enum, unique

枚举类的特性:

  • 定义枚举时,其枚举成员的名称不允许相同
  • 默认情况下,不同的成员值允许相同。但是两个相同值的成员,其第二个成员名称是第一个成员名称的别名;因此在访问枚举成员时,只能获取第一个成员。
  • 如果要限定枚举里面所有的值必须唯一,可以在定义枚举类时,加上@unique
  • 枚举的比较,只能是成员与成员,或者值与值,不能成员与值比较
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

uncle_Huang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值