python面向对象组合-day22

class A:
    Country = 'China'
    def talk(self):
        print('%s is talking'%self.name)
alex = A()          #相当于A(self)
alex.name = 'alex'  #相当于A(self,name)
alex.talk()
一个类可以没有__init__
在没有__init__的情况下,实例化经历了哪些步骤???
    1.创建一个空间给对象
    2.将这个空间的地址返回

class A:
    Country = 'China'
    def __init__(self,name):
        self.name = name
    def talk(self):
        print('%s is talking'%self.name)
#新增静态属性
A.静态属性名 = 'abc'
print(A.静态属性名)
#修改静态属性
A.Country = '印度'
print(A.Country)
#删除静态属性
del A.Country
print(A.Country)   # 报错
#查看类中的方法,只能看,不能改也不能删
print(A.__dict__)

类的命名空间中有什么:
    静态属性(共享给所有对象的)
    动态属性(绑定到所有对象的)

对象的命名空间和类的命名空间之间的关系:
    对象和类之间有一个单向的联系,类对象指针
    创建一个对象/实例就会创建一个对象/实例的名称空间,存放对象/实例的名字,称为对象/实例的属性
    对象在使用某个名字的时候,如果在自己的空间中没有找到,就找父类,如果父类找不到,就要到类的空间中去找,最后到找不到抛异常
    对象可以查看类的静态属性,但是不能修改
    并且一旦修改,就不能取到类当中的内容了(除非手动删除这个修改的属性)
    所有的静态属性的修改,都应该由类名来完成,而不应该使用对象名来完成
class A:
    Country = 'China'
    def __init__(self,name):
        self.name = name
    def talk(self):
     print('%s is talking'%self.name)
alex = A('alex')
baoyuan = A('baoyuan')
print(alex.Country)
alex.Country = '泰国'
print(alex.Country)
del alex.Country
print(alex.Country)
print(A.Country)
print(baoyuan.Country)

静态属性就是用来描述所有的对象都共享的某一个值
class People:
    money = 1000
    def salary(self):
        People.money += 1000
mother = People()
father = People()
mother.salary()
father.salary()
print(People.money,mother.money,father.money)

写一个类,能够记录这个类有多少个对象了(每一次实例化都能够被记录下来)
    class A:
        count = 0
        def __init__(self):
            A.count += 1
    print(A.count)
    a = A()
    print(A.count)
方法二
    class A:
        count = 0
        def __init__(self):
            self.counter()
        def counter(self):
            A.count+=1
    a = A()

class People:
    money = 1000
    def salary(self):
        People.money += 1000
mother = People()
father = People()
mother.salary()
father.salary()
print(People.money,mother.money,father.money)

class B:
    l = []
    def __init__(self,name):
        self.l.append(name)
alex = B('alex')
baoyuan = B('宝元')
print(B.l)
print(alex.l)
print(baoyuan.l)

如果静态变量是一个不可变数据类型,那么只要对象修改这个数据,就相当于在对象的空间中新建
如果静态变量是一个可变数据类型,那么对象修改这个容器中的元素,相当于修改类的空间中的元素
如果静态变量是一个可变数据类型,那么对象直接对这个变量重新赋值,相当于修改对象自己空间中的元素

大结论
只要是静态变量,就用类名去修改,永远修改成功,并且所有的对象都共享这个改变

总结
对象的命名空间:类指针\对象的所有属性
类的命名空间:方法和(静态属性\字段)
对象在寻找名字的时候 : 先找对象自己内存空间中的,找不到就去类的命名空间中寻找
类中的名字是什么时候写入内存的 : 代码从上到下执行的时候就已经写入的.一定是在实例化之前
静态变量 : 尽量用类名去操作

组合 : 一个类对象的属性是另外一个类的对象
class Person:
    def __init__(self,name,sex,hp,mp,ad):
        self.name = name
        self.sex = sex
        self.hp = hp
        self.mp = mp
        self.ad =ad
    def attack(self,dog):
        print('%s攻击了%s'%(self.nme,dog.name))
        dog.hp -= self.ad
class Dog:
    def __init__(self,name,kind,hp,ad):
        self.name = name
        self.kind = kind
        self.hp = hp
        self.ad = ad
    def bite(self,person):
        print('%s咬了%s'%(self.name,person.name))
        person.hp -= self.ad
alex = Person('alex','man',10,10,0.1)
hei = Dog('小黑','中华田园犬',999,1.1)
hei.bite(alex)
class Weapon:
    def __init__(self,name,price,ad):
        self.name = name
        self.price = price
        self.ad = ad
    def skill(self,dog):
        print('%s被%s攻击了'%(dog.name,self.name))
        dog.hp -= self.ad
        print(dog.hp)
sh = Weapon('棍子',9.99,66)
sh.skill(hei)
alex.武器 = sh
alex.武器.skill(hei)
# sh.ad -= 10
alex.武器.skill(hei)
#解耦 (降低耦合)

class Birthday:
    def __init__(self,y,m,d):
        self.y = y
        self.m = m
        self.d = d
class Student:
    def __init__(self,name,sex,birth_day):
        self.name = name
        self.sex = sex
        self.birth_day = birth_day
birth = Birthday(1990,11,22)
bobo = Student('bobo','male',birth)
#bobo.birthday == birth
print(birth.year)
print(bobo.birthday.year)


class Circle:
    def __init__(self,r):
        self.r = r
    def area(self):
        return 3.14*self.r**2
    def perimter(self):
        return 3.14*2*self.r
c1 = Circle(10)
print(c1.area())
print(c1.perimter())

class Ring:
    def __init__(self,outer_r,inner_r):
        self.out_r = outer_r
        self.in_r = inner_r
    def area(self):
        return self.out_r**2*3.14 - self.in_r**2*3.14
    def perimeter(self):
        return self.out_r*2*3.14 - self.in_r*2*3.14
r1 = Ring(10,5)
print(r1.area())
print(r1.perimeter())

圆环是由两个圆组成的,圆环的面积是外面圆的面积减去内部圆的面积。圆环的周长是内部圆的周长加上外部圆的周长。
这个时候,我们就首先实现一个圆形类,计算一个圆的周长和面积。然后在"环形类"中组合圆形的实例作为自己的属性来用
from math import pi
class Circle:
    def __init__(self,r):   #r为圆半径
        self.r = r
    def area(self):
        return pi*self.r**2
    def perimeter(self):
        return pi*self.r*2
c1 = Circle(10)         #实例化一个圆半径为10
print(c1.area())        #计算圆的面积
print(c1.perimeter())   #计算圆的周长
class Ring:
    def __init__(self,outer_r,inner_r):
        self.out_c1 = Circle(outer_r)
        self.in_c2 = Circle(inner_r)
        # c1 = Circle(outer_r)
        # c2 = Circle(inner_r)
        # self.out_c = c1
        # self.in_c = c2
    def area(self):
        return self.out_c1.area() - self.in_c2.area()
    def perimeter(self):
        return self.out_c1.perimeter() + self.in_c2.perimeter()
r1 = Ring(10,5)         #实例化一个环形
print(r1.area())        #计算环形的周长
print(r1.perimeter())   #计算环形的面积

事例二
class BirthDate:
    def __init__(self,year,month,day):
        self.year=year
        self.month=month
        self.day=day

class Couse:
    def __init__(self,name,price,period):
        self.name=name
        self.price=price
        self.period=period

class Teacher:
    def __init__(self,name,gender,birth,course):
        self.name=name
        self.gender=gender
        self.birth=birth
        self.course=course
    def teach(self):
        print('teaching')

p1=Teacher('egon','male',BirthDate('1995','1','27'),
           Couse('python','28000','4 months')
           )
print(p1.birth.year,p1.birth.month,p1.birth.day)
print(p1.course.name,p1.course.price,p1.course.period)
结果
1995 1 27
python 28000 4 months
当类之间有显著不同,并且较小的类是较大的类所需要的组件时,用组合比较好

猜你喜欢

转载自www.cnblogs.com/linuxcbb/p/9991196.html