知识
'''
面向对象变成,思想:角色的抽象,创建类,创建角色(实例化),操作这些实例
面向对象的关键字 class __init__初始化之前川江了一个空对象self,类名加载到内存空间,类里面的变量名字占空间
类名.静态属性,存储在类的命名空间
对象=类名(),实例化
对象可以使用静态变量,类不可以使用对象的属性
组合,一个类的对象是另外一个类的属性
'''
例子
class A:
def __init__(self) -> None:
self.name = 'egon'
class B:
def __init__(self, year, month, day) -> None:
self.year = year
self.month = month
self.day = day
b = B(18, 1, 17)
a = A()
a.birth = b
选课系统tips
'''
题目在https://www.cnblogs.com/Eva-J/articles/7747946.html
1.
登陆之前选择自己的身份,然后输入用户名和密码,程序根据用户的选择去找对应的文件,检查登陆是否成功
2.
登陆的时候输入用户名和密码自动判断身份
'''
初识继承
'''
继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类
一个类 可以被多个类继承,在python中,一个类可以继承多个父类
'''
class A:
pass # 父类,基类,超类 ,父类互不相干
class B:
pass
class A_son(A, B):
pass # 子类,派生类,先有父类,多个儿子,子类互不相干,子类可以找到父类,父类不能找到子类
print(A_son.__base__) # 查看父类,顶端是obiect类,没有继承父类,默认继承object,新式类
'''
只有类与类之间的关系叫做继承,对象和类之间不是
父类中没有的属性在子类中出现,叫做派生属性
父类中没有的方法在子类中出现,叫做派生方法
只要是子类中的对象调用,子类中有的名字,一定用子类的子类中没有才找父类的
父类子类都有,用子类的
如果还想用父类的,单独调用父类的,父类名.方法名,需要自己传self
继承表达的是一种子类是父类的关系
'''
例子
class Animal:
def __init__(self, name, blood, aggr):
self.name = name
self.blood = blood
self.aggr = aggr
def eat(self):
print('吃药回血')
self.blood += 100
class Dog(Animal):
def __init__(self, name, blood, aggr, kind):
Animal.__init__(self, name, blood, aggr)
self.kind = kind # 派生属性
def bite(self, person): # 派生方法
person.blood -= self.aggr
def eat(self):
self.teeth = 2
Animal.eat(self) # 如果既想实现新的功能,也想使用父类原本的功能,还需要再子类中调用父类,必须要传self
class Person(Animal):
def __init__(self, name, blood, aggr, sex):
Animal.__init__(self, name, blood, aggr)
self.sex = sex # 派生属性
self.money = 0
def attack(self, dog): # 派生方法
dog.blood -= self.aggr
jin = Dog('金老板', 100, 200, 'teddy')
jin.eat()
print(jin.blood)
alex = Person('alex', 999, 998, 'None')
alex.eat()
print(alex.blood)
jin.bite(alex)
print(alex.blood)
例子二
'''
狗类 吃 喝 游泳
鸟类 吃 喝 下单
'''
class Animal:
def __init__(self) -> None:
print('执行Animal.__init__')
self.func()
def eat(self):
print('%s eating' % self.name)
def drink(self):
print('%s drinking' % self.name)
def func(self):
print('Animal.func')
class Dog(Animal):
def guard(self):
print('guarding')
def func(self):
print('Dog.func')
dog = Dog()
class Bird(Animal):
def lay(self):
print('laying')
bird = Bird()
dog.drink()
bird.drink()
dog.guard()
bird.lay()
新式类
'''
新式类super
class Animal:
def __init__(self, name, blood, aggr):
self.name = name
self.blood = blood
self.aggr = aggr
def eat(self):
print('吃药回血')
self.blood += 100
class Dog(Animal):
def __init__(self, name, blood, aggr, kind):
super.__init__( name, blood, aggr) # 不需要传self了,已经传了python3中所有的类都是新式类,单继承
self.kind = kind # 派生属性
def eat(self):
print('dog eat)
jin = Dog('金老板', 100, 200, 'teddy')
print(jin.name)
jin.eat()
super(Dog, jin).eat() # 在外部使用,必须传类名和对象名,执行父类的eat()
'''
多继承
class A:
def func(self):
print('a')
class B:
def func(self):
print('b')
class C:
def func(self):
print('c')
class D(A, B, C): # 如果自己的类中没有,调用A的,然后调用B的,然后调用C的,从左到右
pass
# def func(self):
# print('d')
d = D()
print(d.func())
钻石继承问题
class A:
def func(self):
print('a')
class B(A):
def func(self):
print('b')
class C(A):
def func(self):
print('c')
class D(B, C):
def func(self):
print('d')
d = D()
print(d.func())
广度优先
# 新式类采用广度优先的方式,向右为广度,向上为深度,遵循不错过类的原则
class F:
def func(self):
print('f')
class A(F):
def func(self):
print('a')
class B(A):
def func(self):
print('b')
class E(F):
def func(self):
print('e')
class C(E):
def func(self):
print('c')
class D(B, C):
def func(self):
print('d')
d = D()
print(D.mro())
# 顺序为DBACEF
# 多继承中,子类的对象调用一个方法,默认是就近原则
# 经典类深度优先,python2.7经典类和新式类并存
# 新式类广度优先,python3只有新式类
# mro方法旨在新式类存在
# super的本质不是直接找父类,而是根据调用者的节点位置的广度优先顺序来的