一、课前回顾
类:具有相同属性和方法的一类事物
实例化:类名()
过程:
开辟了一块内存空间
执行init方法
封装属性
自动的把self返回给实例化对象的地方
对象:实例
一个实实在在存在的实体
组合:
一个类的对象 作为另一个类对象的属性
让两个类之间产生关系
__dict__():
查看类中所有静态属性和方法
查看所有对象的属性、类对象指针
静态属性:类的属性,所有的对象共享这个变量
对象名:去修改 类的静态属性
在对象的空间中有创建了一个属性,而不能修改类中属性的值
操作静态属性 应该 用类名来操作
二、面向对象的三大特性之继承
2.1继承与抽象两个概念
class Animal: # 父类/超类/基类 def __init__(self,name,kind,food): self.name = name self.kind = kind self.food = food def yell(self): print('喵喵叫') def eat(self): print('吃猫粮') def drink(self): print('喝水') class Cat(Animal): # 类名(父类名) 就是继承 def catch_mouse(self): print('抓老鼠') class Dag(Animal): # 子类/派生类 def look_after_house(self): print('看家')
cat = Cat('阿猫','橘猫','猫粮','喵喵') # 实例化对象
cat.yell()
dag = Dag('阿狗','土狗','狗粮','旺旺')
dag.drink()
结果为:
喵喵叫
喝水
继承:通过子类名(父类名)实现对父类方法的继承。
父类/超类/基类
子类/派生类
2.1.1 继承与重用
class Animal: # 父类/超类/基类 def __init__(self,name,kind,food,language): self.name = name self.kind = kind self.food = food self.language = language def yell(self): print('%s叫'%self.language) def eat(self): print('吃%s'%(self.food)) def drink(self): print('喝水') class Cat(Animal): # 类名(父类名) 就是继承 def catch_mouse(self): print('抓老鼠') class Dag(Animal): # 子类/派生类 def look_after_house(self): print('看家') cat = Cat('阿猫','橘猫','猫粮','喵喵') cat.yell() dag = Dag('阿狗','土狗','狗粮','旺旺') dag.eat() 结果为: 喵喵叫 吃狗粮
重用:猫和狗的叫和吃两个方法属于重用
2.1.2派生属性
当子类中有要被调用的方法的时候,子类的对象会直接选择子类中的方法、变量,父类中的方法不会被自动执行
如果我们既想要执行子类的方法,也想要执行父类的方法,那么需要在子类的方法中调用父类的方法:
1、父类名,方法名(self....)
2、super(),方法名(...)
这样就会帮我们在子类中调用父类中的同名方法
class Animal: # 父类/超类/基类 def __init__(self,name,kind,food,language): self.name = name self.kind = kind self.food = food self.language = language def yell(self): print('%s叫'%self.language) def eat(self): print('吃%s'%(self.food)) def drink(self): print('喝水') class Cat(Animal): # 类名(父类名) 就是继承 def catch_mouse(self): # Animal.drink(self) # 子类方法中调用父类方法 super().drink() print('抓老鼠') class Dag(Animal): # 子类/派生类 def look_after_house(self): print('看家') cat = Cat('阿猫','橘猫','猫粮','喵喵') cat.catch_mouse() 结果为: 喝水 抓老鼠
2.2抽象类
作用:
多人开发、复杂的需求、后期的扩展
手段、来帮助我们完成规范
范例: 只需要了解
from abc import ABCMeta,abstractclassmethod 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(obj,money): obj.pay(money)
抽象类
抽象类是一个规范,他基本不会实现什么具体的功能,抽象类是不能被实例化
要想写有一个抽象类
from abc import ABCMeta,abstractclassmethod
在这个类创建的时候,指定metaclass=ABCMeta
#在你希望子类实现的方法上加一个@abstractmethod装置器
使用抽象类
继承这个类
必须实现这个类中被@abstractmethod装饰器装饰的方法
2.2多继承
class Parent1:pass class Parent2:pass class Son(Parent1,Parent2):pass print(Son.__bases__) # 查看该类继承的所有父类 结果为: (<class '__main__.Parent1'>, <class '__main__.Parent2'>)
# 不是多有的语言都支持多继承 jave
# c++支持多继承
举例:
class Animal: def __init__(self,name): self.name = name class FlyAnimal(Animal): def fly(self): print('%s在飞'%self.name) class WalkAnimal(Animal): def fly(self): print('%s在走路'%self.name) class SwimAnimal(Animal): def fly(self): print('%s在游泳'%self.name) class Tiger(SwimAnimal,WalkAnimal): pass class Swan(SwimAnimal,WalkAnimal,FlyAnimal): pass class Parrot(FlyAnimal,WalkAnimal): def talk(self): print('%s说话了'%self.name) swan = Swan('天鹅') swan.fly() parrot = Parrot('鹦鹉') parrot.talk() parrot.fly()
结果为:
天鹅在游泳
鹦鹉说话了
鹦鹉在飞
三、新式类与经典类
新式类与经典类
新式类
在Python3.0里所有类都是新式类
所有的新式类都有一个默认的父类:object
class Person1:pass class Person2():pass class Person3(object):pass # p = Person() # __init__初始化方法 print(Person1.__bases__) #(<class 'object'>,) print(Person2.__bases__) #(<class 'object'>,) print(Person3.__bases__) #(<class 'object'>,)
python 2.7
经典类与新式类 并存
class Student:pass # 经典类
class Student(object):pass
总结:
继承了object的类就是新式类
在py3中所有的类都是新式类
在py2中既有新式类又有经典类
继承规律:
继承方法是——遵循广度优先
继承object
mro方法
super:super不是单纯的找父类,而是遵循mro顺序的
class A: def func(self): print('A') class B(A): def func(self): super().func() print('B') class C(A): def func(self): super().func() print('C') class D(B,C): def func(self): super().func() print('D') D().func() 结果为: A C B D
图解:
四、类与对象名称空间
1.只要对象的某个属性被直接赋值,那么一定是对象的命名空间发生变化。
2.只要是静态变量,借用类名操作。