python面向对象梳理

1. 类的继承

在OOP(Object Oriented Programming)程序设计中,当我们定义一个class的时候,可以从某个现有的class 继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class)。
我们先来定义一个class Person,表示人,定义属性变量 name 及 sex (姓名和性别);
定义一个方法print_sex()

class Person:
    sex=''
    age=''
    def __init__(self,sex,age):
        self.age=age
        self.sex=sex
    def print_sex(self):
        print(self.sex)

class Male(Person):
    def print_sex(self):
        print('my sex is '+self.sex)
Male('男',23).print_sex()

遵循简单的一句话:自己有就用自己的,没有就看看父类有没有,isinstance(o,t)可以用来检测对象是否是某个类的一个实例,子类是父类的实例,但是父类不会是子类的实例

2.多态

当子类和父类都存在相同的 print_sex()方法时,子类的 print_sex() 覆盖了父类的 print_sex(),在代码运行时,会调用子类的 print_sex()
这样,我们就获得了继承的另一个好处:多态。
多态的好处就是,当我们需要传入更多的子类,例如新增 Teenagers、Grownups 等时,我们只需要继承 Person 类型就可以了,而print_title()方法既可以直不重写(即使用Person的),也可以重写一个特有的。这就是多态的意思。调用方只管调用,不管细节,而当我们新增一种Person的子类时,只要确保新方法编写正确,而不用管原来的代码。这就是著名的“开闭”原则:
对扩展开放(Open for extension):允许子类重写方法函数
对修改封闭(Closed for modification):不重写,直接继承父类方法函数

#调用父类的构造方法
 def __init__(self,name,sex,mother,father):
         Person.__init__(self,name,sex)        
         self.mother = mother
         self.father = father

3.抽象类与接口

什么是抽象类

与java一样,python也有抽象类的概念但是同样需要借助模块实现,抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化

为什么要有抽象类

如果说类是从一堆对象中抽取相同的内容而来的,那么抽象类就是从一堆类中抽取相同的内容而来的,内容包括数据属性和函数属性。
比如我们有香蕉的类,有苹果的类,有桃子的类,从这些类抽取相同的内容就是水果这个抽象的类,你吃水果时,要么是吃一个具体的香蕉,要么是吃一个具体的桃子。。。。。。你永远无法吃到一个叫做水果的东西。
从设计角度去看,如果类是从现实对象抽象而来的,那么抽象类就是基于类抽象而来的(更高层次的抽象)
从实现角度来看,抽象类与普通类的不同之处在于:抽象类中有抽象方法,该类不能被实例化,只能被继承,且子类必须实现抽象方法。这一点与接口有点类似。

#一切皆文件
from abc import ABCMeta,abstractmethod

class All_file(metaclass=ABCMeta):
    all_type='file'
    @abstractmethod #定义抽象方法,无需实现功能
    def read(self):
        '子类必须定义读功能'
        pass

    @abstractmethod #定义抽象方法,无需实现功能
    def write(self):
        '子类必须定义写功能'
        pass


class Txt(All_file): #子类继承抽象类,但是必须定义read和write方法
    def read(self):
        print('文本数据的读取方法')

    def write(self):
        print('文本数据的读取方法')

class Sata(All_file): #子类继承抽象类,但是必须定义read和write方法
    def read(self):
        print('硬盘数据的读取方法')

    def write(self):
        print('硬盘数据的读取方法')

class Process(All_file): #子类继承抽象类,但是必须定义read和write方法
    def read(self):
        print('进程数据的读取方法')

    def write(self):
        print('进程数据的读取方法')

wenbenwenjian=Txt()

yingpanwenjian=Sata()

jinchengwenjian=Process()

#这样大家都是被归一化了,也就是一切皆文件的思想
wenbenwenjian.read()
yingpanwenjian.write()
jinchengwenjian.read()

print(wenbenwenjian.all_type)
print(yingpanwenjian.all_type)
print(jinchengwenjian.all_type)

抽象类与接口的区别

抽象类的本质还是类,指的是一组类的相似性,包括数据属性(如all_type)和函数属性(如read、write),而接口只强调函数属性的相似性。

1.多继承问题
在继承抽象类的过程中,我们应该尽量避免多继承;
而在继承接口的时候,我们反而鼓励你来多继承接口
2.方法的实现
在抽象类中,我们可以对一些抽象方法做出基础实现;
而在接口类中,任何方法都只是一种规范,具体的功能需要子类实现

java中对于类之间的单继承我们很好理解,是为了避免子类被引用的时候同一个方法无法判断应该使用哪个父类的方法,如类One同时继承了类Two和类Three,类Two和类Three中都有printStr方法,当调用pringStr方法的时候,就无法选择使用哪个类的printStr,但是python支持多继承,因此存在一个多继承的优先级问题

#查看一个类的继承顺序
print(Male.__mro__)
#out:(, , )

小口诀,到达顶点之前换方向
例子:
D——C(B(A)),F(E(A)))
D查找父类的优先级 CBFEA

你可能感兴趣的:(python面向对象梳理)