day 19 类的名称空间,组合,派生

时间:2021-08-27 09:40:23

对象的属性: 不仅在__init__里面添加,还可以在其他方法或者类外面添加

class Game:
def __init__(self,name,age):
self.name = name
self.age = age p1 = Game('盖伦', 18)
p1.sex = 'male' # 类外面添加对象属性
print(p1.__dict__)

类的属性: 不仅在类内部添加,还可以在类外面添加

class Game:

    def __init__(self,name,age):
self.name = name
self.age = age Game.tools = '青龙刀' # 类外面添加类的属性
print(Game.__dict__)

对象空间中存在一个类对象指针,所以对象可以找到类中的变量以及方法 (对象可以找类的属性)

类名只能找到类中的变量,方法,后者(父类中的),不能找对象中的属性  (类不能找对象的属性)

组合: 将一个对象封装到另一个对象的属性中

class Game:
def __init__(self,name,ad):
self.name = name
self.ad = ad def attack(self,x):
print('{}攻击{}'.format(self.name,x.name)) def equip_wappon(self,wap):
self.wap = wap # 组合:给一个对象封装一个属性该属性是另一个类的对象
# 给wuda封装一个wuda.wap属性(knife), wuda.wap = knife class Weapon:
def __init__(self,name,ad):
self.name = name
self.ad = ad
def waapon_attack(self,w,s):
print('{} 用 {} 攻击了 {}'.format(w.name,knife.name,s.name))
knife = Weapon('18厘米长棍', 99)
wuda = Game('武大',20)
seman = Game('西门',10)
# wuda.attack(seman)
# knife.waapon_attack(wuda,seman) # 武大 用 18厘米长棍 攻击了 西门
wuda.equip_wappon(knife)
wuda.wap.waapon_attack(wuda,seman) # 武大 用 18厘米长棍 攻击了 西门

组合示例

组合的好处:

   代码更合理

   类与类之间的耦合性增强(并不是好事)

补充: 开发原则,高汇聚,低耦合

继承

继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类

class Animal:
def __init__(self,name,sex,age):
self.name = name
self.sex = sex
self.age = age class Person:
def __init__(self,name,sex,age):
self.name = name
self.sex = sex
self.age = age class Dog:
def __init__(self,name,sex,age):
self.name = name
self.sex = sex
self.age = age
# 以上三种类,都有相似的属性。所以Person、Dog可以继承Animal,减少代码

继承举例

继承的示例:

class Animal:
def __init__(self,name,sex,age):
self.name = name
self.sex = sex
self.age = age class Person(Animal): # (Animal)继承Animal的属性
pass p1 = Person('西门','M',18) # 必须传参数,不然会报错
print(p1.__dict__) # {'name': '西门', 'sex': 'M', 'age': 18} Animal是父类
Person是子类,派生类

单继承

类名:

可以调用父类的属性,方法

class Animal:
type = '动物类'
def __init__(self,name,sex,age):
self.name = name
self.sex = sex
self.age = age
def eat(self):
print('要吃饭') class Person(Animal): # (Animal)继承Animal的属性
# type = '不喜欢吃饭'
pass print(Person.type) # 类名可以调用父类的属性
Person.eat('') # 类名可以调用父类的方法
Person.type = 666 # 这样只是给Person添加type属性,并不能更改父类的type属性
print(Animal.__dict__) # type = '动物类'
print(Person.type)

类名

对象:

对象执行类的父类的属性和方法

class Animal:
type = '动物类'
def __init__(self,name,sex,age):
self.name = name
self.sex = sex
self.age = age
def eat(self):
print('要吃饭') class Person(Animal): # (Animal)继承Animal的属性
type = '不喜欢吃饭'
pass p1 = Person('西门','M',18) # 必须传参数,不然会报错
print(p1.type) # 动物类 可以调用父类的属性
print(p1.type) # 不喜欢吃饭 如果自己有和父类相同的属性,则先用自己的
p1.eat() # 可以调用父类的方法
p1.type = 666 # 这样只是改p1的属性,并不能更改父类的type属性
print(p1.__dict__) # type = '动物类'

对象

继承:单继承,多继承

# python 类:
# 经典类:只存在python2x,不继承object的类,所以python2x既有经典类,又有新式类。
# 新式类:继承object类。python3x所有的类默认都继承object。
# 单继承都一样。
# 多继承不一样:
# 经典类 :深度优先。
# 新式类 : mro 继承顺序,C3算法。
# 既要执行子类方法,也要执行父类方法
class Animal:
type = '动物类'
def __init__(self,name,sex,age):
self.name = name
self.sex = sex
self.age = age
def eat(self):
print('要吃饭') class Person(Animal): # (Animal)继承Animal的属性
def __init__(self, name, sex, age, mind):
# Animal.__init__(self,name,sex,age) #方法一
super().__init__(name, sex, age) # 方法二
self.mind = mind def eat(self):
super().eat() p1 = Person('西门', 'M', 18, '有思想')
print(p1.__dict__)
p1.eat() # 要吃饭
# 方法一: Aniaml.__init__(self,name,sex,age)
# p1 = Person('春哥','laddboy',18,'有思想')
# print(p1.__dict__) # 方法二:super
# p1 = Person('春哥','laddboy',18,'有思想')
# print(p1.__dict__)