python 如何定义抽象类和抽象方法

文章目录

    • (一)python 如何定义抽象类和抽象方法
    • (二)python中的多态
    • (三)类的组合

(一)python 如何定义抽象类和抽象方法

在python中类 通过继承metaclass = ABCmeta类来创建抽象类,抽象类是包含抽象方法的类,其中ABCmeta类(Metaclass for defining abstact baseclasses,抽象基类的元类)是所有抽象类的基类。

定义了抽象类后,在要实现抽象方法的前一行使用@abc.abstractmethod来定义抽象方法。抽象方法不包含任何可实现的代码,只能在子类中实现抽象函数的代码。

抽象类的特点:

  1. 抽象类不能被实例化
  2. 继承抽象类的类必须实现所有的抽象方法后,才能被实例化
  3. 抽象类中有抽象方法和正常方法
  4. 抽象类中可以添加成员属性

注意:

  1. 抽象类中的抽象方法,在子类中必须实现该方法

  2. 抽象类不能被实例化

  3. 创建抽象方法前,必须先创建抽象类

  4. 需要导入abc(abstractclass)类

  5. python是动态语言(在程序运行时检查类型,对比:java是静态语言,在程序运行前检查类型)。动态语言调用实例方法,不检查类型,只要方法存在,参数正确,就可以调用 ;

    也就是说,例如:传递给函数 who_am_i(x)的参数 x 不一定是 Person 或 Person 的子类型。任何数据类型的实例都可以,只要它有一个whoAmI()的方法,且参数正确即可

#coding:utf-8
from abc import ABCMeta, abstractmethod

class Person(object):
    __meta_class__ = ABCMeta

    def __init__(self, **kwargs):
        self.age = kwargs.get("age")
        self.name = kwargs.get("name")

    def hello(self):
        print "hello, my name is {}, and my age is {}".format(self.name, self.age)

    @abstractmethod
    def say(self):
        pass


class Student(Person):
    def __init__(self, **kwargs):
        super(Student, self).__init__(**kwargs)
        self.school = kwargs.get("school")

    def say(self):
        print "my school is ", self.school

stu = Student(name="wangming", age=19, school="Henan Politecnic University")
stu.hello()
stu.say()

运行结果:

hello, my name is wangming, and my age is 19
my school is  Henan Politecnic University

(二)python中的多态

  1. 子类可以继承父类的方法或者属性

  2. 子类也可以重写父类的方法或者属性,子类在重写父类的方法时可以改变函数的参数和方法体以及输出内容

  3. 对象在调用某个方法时,总是先查找它自身的定义,如果没有定义,则顺着继承链向上查找,直到在某个父类中找到为止

  4. 由于Python是动态语言,所以,传递给函数 who_am_i(x)的参数 x 不一定是 Person 或 Person 的子类型。任何数据类型的实例都可以,只要它有一个whoAmI()的方法即可

类具有继承关系,并且子类类型可以向上转型看做父类类型,如果我们从 Person 派生出 Student和Teacher ,并都写了一个 whoAmI() 方法:

class Person(object):
    def init(self, name, gender):
        self.name = name
        self.gender = gender

    def whoAmI(self):
        return 'I am a Person, my name is %s' % self.name

class Student(Person):
    def init(self, name, gender, score):
        super(Student, self).init(name, gender)
        self.score = score

    def whoAmI(self):
        return 'I am a Student, my name is %s' % self.name

class Teacher(Person):
    def init(self, name, gender, course):
        super(Teacher, self).init(name, gender)#继承父类的初始化函数__init__()
        #Person.init(self, name, gender) #效果同上
        
        self.course = course

    def whoAmI(self):
        return 'I am a Teacher, my name is %s' % self.name

#在一个函数中,如果我们接收一个变量 x,则无论该 x 是 Person、Student还是 Teacher,都可以正确打印出结果:

def who_am_i(x):
    print x.whoAmI()

p = Person('Tim', 'Male')
s = Student('Bob', 'Male', 88)
t = Teacher('Alice', 'Female', 'English')

who_am_i(p)
who_am_i(s)
who_am_i(t)

运行结果:

I am a Person, my name is Tim
I am a Student, my name is Bob
I am a Teacher, my name is Alice
这种行为称为多态。

也就是说,方法调用将作用在 x 的实际类型上。s 是Student类型,它实际上拥有自己的 whoAmI()方法以及从 Person继承的 whoAmI方法,但调用 s.whoAmI()总是先查找它自身的定义,如果没有定义,则顺着继承链向上查找,直到在某个父类中找到为止

由于Python是动态语言,所以,传递给函数 who_am_i(x)的参数 x 不一定是 Person 或 Person 的子类型。任何数据类型的实例都可以,只要它有一个whoAmI()的方法即可:

class Book(object):
def whoAmI(self):
return ‘I am a book’
这是动态语言和静态语言(例如Java)最大的差别之一。动态语言调用实例方法,不检查类型,只要方法存在,参数正确,就可以调用。

(三)类的组合

'''
1.class类的组合使用
2.手机、邮箱、QQ等是可以变化的(定义在一起),姓名不可变(单独定义)。
3.在另一个类中引用
'''
 
 
class Info(object):
    def __init__(self, phone, email, qq):
        self.phone = phone
        self.email = email
        self.qq = qq
 
    def get_phone(self):
        return self.phone
 
    def update_phone(self, newphone):
        self.phone = newphone
        print u"手机号更改已更改"
 
    def get_email(self):
        return self.email
 
class AddrBook(object):
    '''docstring for AddBook'''
    def __init__(self, name, phone, email, qq):
        self.name = name
        self.info = Info(phone, email, qq)
 
if __name__ == "__main__":
    Detian = AddrBook('handetian', '18210413001', '[email protected]', '123456')
    print Detian.info.get_phone()
    Detian.info.update_phone(18210413002)
    print Detian.info.get_phone()
    print Detian.info.get_email()

你可能感兴趣的:(python基础)