面向对象


类的定义 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不崇尚继承,崇尚鸭子类型
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值