内容大纲:
一、类与对象回顾
二、类和对象的命名空间(易理解错的地方)
三、继承和抽象
四、单继承(继承与重用、继承与派生、抽象类)
五、多继承(多继承、接口类、新式类与经典类)
一、类与对象内容回顾
类:具有相同属性和方法的一类事物
实例化:类名()
1、开辟一个内存空间
2、执行init
3、封装属性
4、自动把self返回实例化对象
对象实例:一个实实在在的实体,类的具体体现
组合:一个类的对象作为另一个类的对象的属性。让两个类之间产生关联
__dict__方法:
1、在类中:查看类中所有的属性和方法
2、对象中:查看对象中的所有属性
二、类和对象的命名空间(易理解错的地方)
1、对象去修改类中的静态属性,是在对象的空间中又创建了一个属性,不能修改类中的属性
class Foo: count = 0 def __init__(self): self.count += 1 f1 = Foo() f2 = Foo() print(Foo.count) #0 print(f1.count) #1 print(f2.count) #1
2、当类中的属性发生改变时,对象中没有同名的属性和方法时,对象使用属性名会跟着类中的变量走
class Foo: count = 0 def __init__(self): Foo.count += 1 f1 = Foo() print(f1.count) # 1 f2 = Foo() f3 = Foo() f4 = Foo() f5 = Foo() print(f1.count) # 5 print(f5.count) # 5 print(Foo.count) # 5
3、只要对象中的某些属性被直接赋值,那么一定是对象的命名空间发生变化
总结:只要是静态变量,就用类名操作
class Foo: count = [0] f1 = Foo() f1.count[0] += 1 print(f1.count[0]) # 1 print(Foo.count[0]) # 1 f1.count = [2] print(f1.count) #[2] print(Foo.count) #[1]
三、继承和抽象
继承和抽象:先抽象,后继承
抽象:抽取类似或比较像的部分
继承:基于抽象的结果,通过编程语言去实现,肯定先经历抽象过程,才能通过继承的方式去表达抽象的结构
四、单继承(继承与重用、继承与派生、抽象类)
1、语法:class 类名(父类名):
父类:又叫超类、基类
子类:又叫派生类
2、继承与重用:父类中的所有属性和方法都可以被子类使用
3、继承与派生:子类在父类的基础上创建新的属性和方法
父类有的子类没有:子类对象直接调用,就会执行父类的方法
父类有的子类也有:子类对象调用就会直接执行子类中的方法,要想调用父类中的方法,用父类名.方法(要加self,.....),或super().方法(....)
4、规范的编程模式(抽象类)
① 抽象类:抽象类是一个规范,它基本不会实现什么功能,抽象类是不能被实例化的
② 写一个抽象类:
from abc import ABCMeta,abstramethod
在这个类创建的时候指定 metaclass = ABCMeta
在你希望子类实现的方法上加上 @abstramethod 装饰器
③ 使用这个抽象类
继承这个类
必须实现类中被@abstramethod 装饰器装饰的方法
from abc import ABCMeta,abstractmethod class Payment(metaclass=ABCMeta): @abstractmethod def pay(self):pass class Alipay(Payment): def pay(self,money): print('使用支付宝支付了%s元' % money) class Wechatpay(Payment): def pay(self,money): print('使用微信支付了%s元' % money) class ApplePay(Payment): def pay(self,money): print('使用applepay支付了%s元' % money) def pay(object,money): object.pay(money) # p = Payment() #抽象类不能实例化,TypeError: Can't instantiate abstract class Payment with abstract methods pay a = Alipay() a.pay(100) #使用支付宝支付了100元 pay(a,100) #使用支付宝支付了100元
五、多继承(多继承、接口类、新式类与经典类)
不是多有的语言都支持多继承(Java,c#)
1、语法:class 类名(父类1,父类2):
class Animal(): def __init__(self,name): self.name = name class Flyanimal(Animal): def fly(self): print('%s会飞'%self.name) class Walkanimal(Animal): def walk(self): print('%s在走路'%self.name) class Swimanimal(Animal): def swim(self): print('%s在游泳'%self.name) class Tiger(Swimanimal,Walkanimal): pass class Swan(Swimanimal,Walkanimal,Flyanimal): pass class Parrot(Walkanimal,Flyanimal): def talk(self): print('%s说话了'%self.name) swan = Swan('天鹅') swan.fly() swan.swim()
2、接口
Java、C#不允许多继承
接口 Interface 可以被多继承
Interface FlyAnimal: def fly():pass #接口中的方法函数中不能有内容 Interface SwimAnimal: def swim():pass Interface WalkAnimal: def walk():pass class Tiger(SwimAnimal,WalkAnimal): def walk(self):代码 #在调用时,要完成代码 def swim(self):代码
3、新式类和经典类
在python 3.x版本中,所有类都是新式类
class Person1:pass
class Person1():pass
class Person1(object):pass #这三个是相同的
在python 2.7中,新式类和经典类并存,继承了object就是新式类
class Student:pass #经典类
class Student(object):pass #新式类
新式类:① 所有多继承关系寻找方法的顺序---广度优先算法
② 主动继承object
③ 有mro方法:查看调用顺序,类名.mro()
④ super:super不是单纯的寻找父类,而是遵循mro顺序
经典类:
① python2.x版本
② 不主动继承object
③ 经典类中寻找父类中的方法遵循--深度优先算法
④ 不提供mro和super
4、广度优先算法和深度优先算法