面向对象


类的定义 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经典类和新式类 并存
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__)

day25 1121:
一、两个类中有相同的代码,引申出继承:继承
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不崇尚继承,崇尚鸭子类型
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章