类
类的定义 class关键字 类名的首字母大写
类中直接定义属性:静态属性(变量) 和 动态属性(函数)
类名的两个作用:属性的引用,实例化对象
类名和属性的操作:对象名.属性名 对象名.__dict__['属性名'](不能修改)#########(可以修改的)##########
实例化 ——类名(参数)
构造方法:造对象
初始化__init__:给这个赤裸裸的对象添加一些属性 __init__
返回了一个初始化之后的对象
__init__方法:初始化方法,可以没有。给对象添加一些必要的基础属性
self的含义:就是这个对象本身
对象和属性的操作:对象名.属性名 对象名.__dict__['属性名']
类的定义 class关键字 类名的首字母大写
类中直接定义属性:静态属性(变量) 和 动态属性(函数)
类名的两个作用:属性的引用,实例化对象
类名和属性的操作:对象名.属性名 对象名.__dict__['属性名'](不能修改)#########(可以修改的)##########
实例化 ——类名(参数)
构造方法:造对象
初始化__init__:给这个赤裸裸的对象添加一些属性 __init__
返回了一个初始化之后的对象
__init__方法:初始化方法,可以没有。给对象添加一些必要的基础属性
self的含义:就是这个对象本身
对象和属性的操作:对象名.属性名 对象名.__dict__['属性名']
def 函数名():
'''函数体'''
pass
class Person:#类名有两个作用
country ='中国'#静态属性、数据属性
defwalk(self):#动态属性、函数属性、方法
print('walk')
一
、
属性:静态属性(直接和类名关联或者直接定义在class下的变量)
对象属性(在类内和self关联,在类外和对象名关联的变量)
动态属性(函数)
class Foo:
country = 'China'
country_lst = ['China']
def__init__(self,name):
self.name = name
alex = Foo('alexander')
egg = Foo('egon')
alex.age = 90
alex.country_lst = []
alex.country_lst.append('印度')
类名操作变量 不管操作可变还是不可变数据类型 都是类中对应的变量发生变化对象名操作静态变量引用变量:现在自己的命名空间中查找,找不到就去类的命名空间找修改变量:如果是对可变数据类型中的元素进行修改,那么全局生效如果是对变量进行重新赋值,那么只是在对象自己的命名空间里增加了一个新的属性结论:应该尽量用类名去使用静态变量
二、
面试一、classFoo: count = 0 def__init__(self): Foo.count += 1 f = Foo() f2 = Foo() f3 = Foo() print(f.count)#Foo.count ## 3 print(f2.count)#Foo.count ## 3 print(f3.count)#Foo.count ## 3
面试二、设计一个类,统计这个类被实例化的次数,且所有的对象共享这个属性classFoo: count = 0 def__init__(self): Foo.count += 1 f = Foo() print(f.count## 1 f2 = Foo() print(f.count)## 2 f3 = Foo() print(f3.count)## 3
三、小栗子
class Person:
def __init__(self):pass#给一个什么属性都没有的对象赋一些初识的属性
def eat(self):
print('吃猪食')
alex = Person() #裸着
print(alex.__dict__)# {}
alex.name = 'alexander'
print(alex.__dict__)# {'name': 'alexander'}
alex.eat = '泔水'#对象使用名字的顺序:先用自己的,再用类的
print(alex.eat)# 泔水
# alex.eat() # 若没有 泔水,则吃猪食,否则报错
#对象可以使用类的
#而类无法使用对象的
print(Person.eat)# <function Person.eat at 0x000000000257A400>
print(alex.eat)#类对象指针的东西 alex = {'eat':eat} # 泔水
四、
函数(定义 调用 返回值 参数、命名空间和作用域);面向对象(定义 、命名空间)三大特性:封装继承和多态(组合);组合 : 什么 有 什么 的关系一个对象的属性是另外一个类的对象①老师有生日②圆形有圆环frommath importpi classCircle: def__init__(self,r): self.radius = r defperimeter(self): return2*pi*self.radius defarea(self): returnpi*(self.radius**2) #环形类 classRing: def__init__(self,outer_r,inner_r): self.outer_circle = Circle(outer_r) self.inner_circle = Circle(inner_r) defperimeter(self): returnself.outer_circle.perimeter()+self.inner_circle.perimeter() defarea(self): returnself.outer_circle.area() -self.inner_circle.area() ring1 = Ring(20,10) print(ring1.area())
人狗大战用组合:
class Dog: # 定义一个狗类
def __init__(self, name, breed, aggressivity, life_value):
self.name = name # 每一只狗都有自己的昵称;
self.breed = breed # 每一只狗都有自己的品种;
self.aggressivity = aggressivity # 每一只狗都有自己的攻击力;
self.life_value = life_value # 每一只狗都有自己的生命值;
def bite(self,people):
people.life_value -= self.aggressivity
class Person: # 定义一个人类
def __init__(self, name, aggressivity, life_value, money):
self.name = name # 每一个角色都有自己的昵称;
self.aggressivity = aggressivity # 每一个角色都有自己的攻击力;
self.life_value = life_value # 每一个角色都有自己的生命值;
self.money = money
def attack(self,dog):
dog.life_value -= self.aggressivity
def get_weapon(self,weapon_obj):
if self.money > weapon_obj.price:
self.money -= weapon_obj.price # 金老板花钱买武器
self.weapon = weapon_obj # 金老板装备打狗棒
self.aggressivity += weapon_obj.aggr # 金老板的攻击力增加了
#不公平#武器装备#人 有 武器 —— 组合
#武器:攻击力,名字,价格
class Weapon:
def __init__(self,name,price,aggr):
self.name = name
self.price = price
self.aggr = aggr
dgb = Weapon('打狗棒',99.8,100)
boss_gold = Person('金老板',5,250,100)
huang = Dog('大黄','藏獒',100,3000)
boss_gold.get_weapon(dgb)
boss_gold.attack(huang)
print(huang.life_value)
---------------------------------------------------------------
python两种类:经典类 新式类
python3新式类 ——都默认继承objectclass Animal(object): ==class Animal:
python2经典类和新式类 并存
python3新式类 ——都默认继承objectclass Animal(object): ==class Animal:
python2经典类和新式类 并存
class Animal:经典类 ——继承顺序个别使用方法class Animal(object):新式类
----------------------------------------------------------------
继承:把相同的代码放在父类中,子类的对象在子类中没有找到方法的时候,使用父类的
class Animal:
def __init__(self,name,aggressivity,life_value):
self.name = name
self.aggressivity = aggressivity
self.life_value = life_value
class Dog(Animal): # 定义一个狗类
def bite(self,people):
people.life_value -= self.aggressivity
class Person(Animal): # 定义一个人类
def attack(self,dog):
dog.life_value -= self.aggressivity
def get_weapon(self,weapon_obj):
if self.money > weapon_obj.price:
self.money -= weapon_obj.price # 金老板花钱买武器
self.weapon = weapon_obj # 金老板装备打狗棒
self.aggressivity += weapon_obj.aggr # 金老板的攻击力增加了
huang = Dog('大黄',100,3000) #__init__ 找父类
print(huang.life_value)
boss_gold = Person('金老板',5,250) #__init__ 自己没有 找父类
print(boss_gold.life_value)
# Dog.bite(Person)
print(Dog.__bases__)
print(Animal.__bases__)
一、两个类中有相同的代码,引申出继承:继承
1、继承
:把相同的代码放在父类中,子类的对象在子类中没有找到方法的时候,使用父类的
①单继承和多继承 ②父类 超类 基类 ③子类 派生类
④抽象(模糊到具体)和继承(具体到模糊) 先抽象后继承
2、两个比较6的具体事例:
他大舅他二舅都是他舅 —— 实例化
高桌子低板凳都是木头 —— 继承
3、小栗子:
class Animal:
pass
def __init__(self,sleep):
self.sleep = sleep
class Cat(Animal):
def __init__(self, eat, drink,sleep):
super().__init__(sleep)
self.eat = eat
self.drink = drink
def door(self):
print('door')
class Dog(Animal):
def fish(self):
print('yu')
hua = Cat(1,2,3)
hua.door() # door
print(hua.eat) # 1
print(hua.sleep) # 3
4、
派生属性 : 在自己的init方法里 使用父类的init方法 —— 指名道姓调用方法
派生方法 : 在子类中增加父类没有的
只要子类有,就用子类的
只要想用父类,Animal.eat(snoopy) 父类名.父类的方法(子类对象)2.7经典类中
5、
class Animal:
def __init__(self,aggressivity, life_value,name):
self.name = name # 每一个角色都有自己的昵称;
self.aggressivity = aggressivity # 每一个角色都有自己的攻击力;
self.life_value = life_value # 每一个角色都有自己的生命值;
def eat(self):
self.life_value += 10
class Person(Animal):
def __init__(self, name, aggressivity, life_value, money):
# Animal.__init__(self, name, aggressivity, life_value)
super().__init__(name, aggressivity, life_value) #新式类
self.money = money #派生属性:父类没有的属性
def attack(self,dog):
dog.life_value -= self.aggressivity
def get_weapon(self,weapon_obj):
if self.money > weapon_obj.price:
self.money -= weapon_obj.price # 金老板花钱买武器
self.weapon = weapon_obj # 金老板装备打狗棒
self.aggressivity += weapon_obj.aggr # 金老板的攻击力增加了
class Dog(Animal):
def __init__(self, name, breed, aggressivity, life_value):
# Animal.__init__(self,aggressivity,life_value,name)
# super(Dog,self).__init__(aggressivity,life_value,name)
super().__init__(aggressivity,life_value,name)
self.breed = breed # 每一只狗都有自己的品种; #派生属性:父类没有的属性
def bite(self,people): # 派生方法 :父类没有的方法
people.life_value -= self.aggressivity
def eat(self):
# Animal.eat(self)
super().eat()
print('dog is eating')
snoopy = Dog('太白','京巴',250,500)
print(snoopy.breed) # 京巴
print(snoopy.name) # 太白
snoopy.eat() # dog is eating
print(snoopy.life_value) # 510
super(Dog,snoopy).eat() #Animal.eat(snoopy) # 外部也可以用super需要制定参数。 # 这个是加血不是吃!!!!!
print(snoopy.life_value) # 520
总结:
用子类的对象,调用父类的方法: 如果子类中没有这个方法,直接就使用父类的 如果子类中有同名方法: 经典类 指名道姓 类名.方法名(子类对象) 类内外一致 新式类 super方法super(子类名,子类对象).方法名() 类内可以省略super的参数
二、面试:
class Foo:
def __init__(self):
self.func()
def func():
print(" this is Foo.func")
class Son(Foo):
def func():
print('this is Son.func')
s = Son # ## this is Son.func(调用自己的func)
实例化子类会调用初始化方法(子类没有调父类)
三、钻石继承问题
用子类的对象,调用父类的方法: 如果子类中没有这个方法,直接就使用父类的 如果子类中有同名方法: 经典类 指名道姓 类名.方法名(子类对象) 类内外一致 新式类 super方法super(子类名,子类对象).方法名() 类内可以省略super的参数
class D:
def f(self):
print('D')
class B(D):
def f(self):
print('B')
class C(E):
def f(self):
print('C')
class A(B,C):
def f(self):
print('A')
a = A()
a.f()
print(A.mro()) 新式类:查看继承顺序
class A(object):pass 新式类
class A(object):pass 新式类 在好多个有继承关系的类里面,找一个方法,找的顺序问题 继承三层(一般) py3 ——广度优先(只有,因为3 没有经典类) py2 ——新式类在好多个有继承关系的类里面,找一个方法,找的顺序问题 继承三层(一般) py3 ——广度优先(只有,因为3 没有经典类) py2 ——新式类
面试 —— 能对应 新式类 是广度优先 经典类是深度优先
四、多态
python中自带多态。
走的像鸭子,教的像鸭子就认为是鸭子
python不崇尚继承,崇尚鸭子类型