day13-面向对象

#解决同一类问题,使用面向对象的思想。类是制造对象的模具,类是抽象的,我们能知道它有哪些属性(name,age,saraly),但不知道具体的属性值。
#看下面代码:类Penson制造了实例化对象ret,它有具体的属性值。
# 一、
class Penson:  #类名首字母大写。这里Penson或Penson()都可以。
    job = 'programmer' #类属性(静态属性)

    def __init__(self,*args): #这四行代码是属性,__init__是初始化方法,self是空字典,*args是必须传参数的元组。
        self.name = args[0]   #self增加属性(添加键值对)。
        self.age = args[1]
        self.saraly = args[2] #self返回给Penson,而ret = Penson,所以ret = Penson = self。

    def func(self,n): #这两行代码是方法。
        print('{},{}岁,年收入{}万,每天学习最少{}个小时'.format(self.name,self.age,self.saraly,n)) #类名.属性名 调用属性:self.name

ret = Penson('xiaoming',30,80) #此操作是实例化,ret是实例化对象。
ret.func(2) #调用方法。对象名.方法名(参数)相当于类名.方法名(实例化对象,参数):Penson.func(ret,2) 。结果是:xiaoming,30岁,年收入80万,每天学习最少2个小时
ret = Penson('tom',20,10)
ret.func(3) #结果是:tom,20岁,年收入10万,每天学习最少3个小时
#面向对象的好处:方便增加人物、代码精简、方便修改。
print(Penson.job)  #查看类属性
print(ret.job)  #查看类属性
print(ret.name) #查看属性
print(ret.age)  #查看属性
print(ret.saraly)#查看属性
print(ret.__dict__) #查看所有属性,结果是{'name': 'tom', 'age': 20, 'saraly': 10},除了类属性:job = 'programmer'
ret.name = 'marry' #修改属性
print(ret.name) #marry

# 二、验证self是字典、ret = self:
class Penson:
    def __init__(self,name):
        print(self.__dict__)  #结果是{}
        self.name = name
        print(self.__dict__) #结果是{'name': 'xiaoming'},证明self是字典。
        print(id(self.__dict__)) #8376656
    def func(self,n):
        print('{},32岁,年收入100万,每天学习最少{}个小时'.format(self.name,n))
ret = Penson('xiaoming')
ret.func(3)
print(id(ret.__dict__)) #8376656,ret.__dict__和self.__dict__地址一样,证明ret = self。

# 三、练习:传入不同的半径,计算面积和周长:
from math import pi
class Math:
    def __init__(self,r):
        self.r = r
    def areas(self):
        print('面积是{}'.format(pi*self.r**2))
    def perimeter(self):
        print('周长是%s,%s'%(self.r*2*pi,self.r))
ret = Math(2)
ret.areas()
ret.perimeter()
ret = Math(1)
ret.areas()
ret.perimeter()

# 四、命名空间:类的命名空间讲述的是对象的类属性修改或重新赋值之后,对类属性的影响。
    #1.不可变数据类型:重新赋值是单独的。
class Penson:
    job = 'programmer' #'programmer'是字符串,是不可变数据类型。类属性(静态属性、静态变量)存在于类的命名空间当中。
    def __init__(self,*args):
        self.name = args[0]
        self.age = args[1]
        self.saraly = args[2]
    def func(self,n):
        print('{},{}岁,年收入{}万,每天学习最少{}个小时'.format(self.name,self.age,self.saraly,n))
ret = Penson('xiaoming',30,80)
ret1 = Penson('tom',30,80)
print(Penson.job) #programmer
print(ret.job)    #programmer
print(ret1.job)   #programmer
ret1.job = 'teacher'  #字符串无法修改,此操作是重新赋值,相当于增加新的类属性(新对象)
print(Penson.job) #programmer
print(ret.job)    #programmer
print(ret1.job)   #teacher
del ret1.job  #删除ret1的类属性,它的类属性变回‘programmer’
print(Penson.job) #programmer
print(ret.job)    #programmer
print(ret1.job)   #programmer

    #2.可变数据类型:修改是共享的,重新赋值是单独的。
     #2.1 修改是共享的:
class Penson:
    job = ['programmer'] #列表是可变数据类型。
    def __init__(self,*args):
        self.name = args[0]
        self.age = args[1]
        self.saraly = args[2]
    def func(self,n):
        print('{},{}岁,年收入{}万,每天学习最少{}个小时'.format(self.name,self.age,self.saraly,n))
ret = Penson('xiaoming',30,80)
ret1 = Penson('tom',30,80)
print(Penson.job) #['programmer']
print(ret.job)    #['programmer']
print(ret1.job)   #['programmer']
ret1.job[0] = 'teacher'  #修改ret1的类属性,没有增加新属性。
print(Penson.job) #['teacher']
print(ret.job)    #['teacher']
print(ret1.job)   #['teacher']
del ret1.job[0]  #删除ret1的类属性,Penson、ret、ret1的类属性变成空列表[]
print(Penson.job) #[]
print(ret.job)    #[]
print(ret1.job)   #[]

     #2.2 重新赋值是单独的:
ret = Penson('xiaoming',30,80)
ret1 = Penson('tom',30,80)
print(Penson.job) #['programmer']
print(ret.job)    #['programmer']
print(ret1.job)   #['programmer']
ret1.job = ['teacher']  #重新赋值,相当于增加新属性,新属性是ret1自己的,没共享给Penson和ret.
print(Penson.job) #['programmer']
print(ret.job)    #['programmer']
print(ret1.job)   #['teacher']
del ret1.job  #删除ret1的类属性,ret1的类属性变回['programmer']
print(Penson.job) #['programmer']
print(ret.job)    #['programmer']
print(ret1.job)   #['programmer']

    #3.1 练习:
class Family:
    money = 0
mother = Family()
father = Family()
mother.money += 1000
father.money += 1000
print(mother.money) #1000,妈妈的钱进了自己的账。因为mother在自己的命名空间当中创建了新的属性。
print(father.money) #1000,爸爸的钱也进了自己的账。
print(Family.money) #家庭进账是0,因为mother、father、Penson是不同的命名空间。参考下面代码:

class Family:
    money = 0
    def work(self):
        Family.money += 1000 #类属性(静态属性、静态变量)存在于类的命名空间当中
mother = Family()
father = Family()
mother.work()
father.work()
print(mother.money) #2000
print(father.money) #2000
print(Family.money) #2000

    #3.2 练习:创建一个类,每实例化一个对象就计数,最后所有对象都共享这个数据。
class Penson:
    count = 0
    def __init__(self):
        Penson.count += 1 #类属性(静态属性、静态变量)存在于类的命名空间当中
func1 = Penson() #一调用Penson就启动__init__方法。
func2 = Penson()
print(func1.count) #2
print(func2.count) #2
func3 = Penson()
print(func1.count) #3
print(func2.count) #3
print(func3.count) #3

#五.在类的外面进行属性的增删改查:
class Penson:
    a = 100000
    def __init__(self):
        self.money = 0
poor = Penson()
print(poor.money)   #0
poor.rmb = 8000000  #增加新属性:对象增加新属性,Penson没有这个属性。
print(poor.rmb)     #8000000  ,查看属性
print(poor.__dict__) #{'money': 0, 'rmb': 8000000},查看除了类属性之外的所有属性,类属性是a = 100000。
del poor.money  #删除属性
print(poor.__dict__) #{'rmb': 8000000}
poor.rmb = 10000000  # 修改属性
print(poor.__dict__)  #{'rmb': 10000000}
print(poor.a) #100000

#六:练习:人狗大战:
# 1.面向对象的交互(Penson类里面有Dog类的对象,Dog类里面有Penson类的对象)
# 2.组合:对象属性是另外一个类的对象。
class Penson:
    def __init__(self,name,aggr,hp): #姓名、攻击力、血
        self.name = name
        self.aggr = aggr
        self.hp = hp
        self.money = 0
    def attack(self,dog):    #定义攻击技能。
        dog.hp -= self.aggr  #人攻击狗,狗掉血。狗掉的血等于人的攻击力。另外一个类的对象属性dog.hp可以在本类当中修改。
    def get_weapon(self,weapon): #定义得到装备技能。调用此技能,就可以得到装备。
        if self.money > weapon.money: #得到装备之前,要判断人的钱是否多于装备的钱
            self.money -= weapon.money
            self.weapon = weapon       #增加装备属性(得到装备)。组合:对象属性是另外一个类的对象。
        else:
            print('余额不足,请先充值')

class Dog:
    def __init__(self,name,aggr,hp):
        self.name = name
        self.aggr = aggr
        self.hp = hp
    def bite(self,penson):
        penson.hp -= self.aggr  #狗咬人,人掉血。

class Weapon:
    def __init__(self,name,aggr,count,money):
        self.name = name
        self.aggr = aggr
        self.count = count #装备可用的攻击次数
        self.money = money
    def att(self,dog):
        if self.count >0: #攻击狗之前,要先判断装备的攻击次数是否大于0
            dog.hp -= self.aggr
            self.count -= 1
        else:
            print('装备可用的攻击次数为0')

alex = Penson('alex',20,10)
alex.money = 1000  #充值
jin = Dog('jin',200,50)
w = Weapon('打狗棒',10,3,900)
alex.attack(jin)
print(jin.hp)         #50-20=30
alex.get_weapon(w)  #调用装备,得到装备。把w传给Penson类里面def get_weapon(self,weapon)这句代码的weapon.
alex.weapon.att(jin) #使用装备攻击狗。因为在Penson类里面,self.weapon = weapon,对象属性是另外一个类的对象,所以alex.weapon.att(jin)相当于w.att(jin),调用Weapon类的att技能。
#因为w.att(jin)装备攻击狗,不符合逻辑,而人调用装备,得到装备,使用装备攻击狗才是符合逻辑的,所以要想办法把w传给人,那么,人增加对象属性就可以了:self.weapon = w。
print(jin.hp)         #30-10=20
jin.bite(alex)
print(alex.hp)
#人调用装备--得到装备--利用装备的技能攻击狗:
def get_weapon(self,weapon): #定义调用装备技能
    self.weapon = weapon # 得到装备
alex.get_weapon(w) #人调用装备--装备传入给人
alex.weapon.att(jin) #利用装备的技能攻击狗

#七.组合:对象属性是另外一个类的对象,这样就可以调用另外一个类的对象方法了。反过来,对象方法可以被另外一个类的对象属性引用。
from math import pi
class Math:
    def __init__(self,r):
        self.r = r
    def areas(self):
        return pi*self.r**2
    def perimeter(self):
        return 2*pi*self.r

class Circle:
    def __init__(self,outside_r,inside_r):
        self.outside_c = Math(outside_r)  #组合:对象属性是另外一个类的对象。
        self.inside_c = Math(inside_r)
    def areas(self):
        return self.outside_c.areas()-self.inside_c.areas() #调用另外一个类的对象方法

c = Circle(20,10)
print(c.areas())

 

上一篇:宁波实习day13


下一篇:day13_面向对象(抽象类丶接口)