面向对象之组合

一 类的命名空间

 1 对于类的静态属性:如果类.属性:调用的解释累的属性

          对象.属性:就是先从自己的命名空间寻找,如果有就用自己的,没有就到类里面去寻找,如果有就用类里面的,没有就会报错。

实例:

# class A:
#     ret='fang'
# a=A()
# print(A.ret)
# print(a.ret)
# a.ret='famgjie'
# print(a.ret)
# print(A.ret)

 2 关于类的动态属性(方法):这个方法本身就存在于类的空间,根本不会存在对象的内存中。

          如果在对象调用类里面的方法,需要在类的内存中产生一个地址簿来对应类中的方法。

# class A:
#     def func(self):
#         print(111)
# a=A()
# a.func()
# a.func=666
# print(a.func)
# a.func()   #这个就报错了

 3 关于对象的属性:对象的属性只存在于对象的命名空间,          

          只能被对象来调用和修改,如果类来调用或修改就会报错。

# class A:
#     pass
# a=A()
# a.name='alex'
# print(a.name)
# print(A.name)    #这个就会报错

二 面向对象的组合

 1 什么叫组合:一个类的对象是另一个类的属性就叫做组合,组合表达的是什么和什么的关系。

 2 组合的好处:增强了代码的重用性。

 实例1 :计算圆环的面积差和圆环面积总周长

import math
class Yuan:
    def __init__(self,ban):
        self.ban=ban
    def mian(self):
        return math.pi*self.ban**2
    def zhou(self):
        return math.pi*self.ban*2
class DaXiaoYuan:
    def __init__(self,daban,xiaoban):
        self.dayuan=Yuan(daban)
        self.xiaoyuan=Yuan(xiaoban)
    def mian(self):
        return self.dayuan.mian() - self.xiaoyuan.mian()
    def zhou(self):
        return self.dayuan.zhou() + self.xiaoyuan.zhou()
yuan=DaXiaoYuan(20,10)
print(yuan.mian())
print(yuan.zhou())

 实例2:课程和学生关联

# class Course:
#     def __init__(self,course_name,period,price,teacher):
#         self.course_name=course_name
#         self.period=period
#         self.price=price
#         self.teacher=teacher
# class People:
#     def __init__(self,name,age,sex,course):
#         self.name=name
#         self.age=age
#         self.sex=sex
#         self.course=course
# py=Course('python',8,20000,'景姐姐')
# stdent_1=People('fang',18,'男',py)
# print(stdent_1.course.period)

 实例3:人狗大战

# class People:
#     def __init__(self,name,sex,aggr,blood):
#         self.name=name
#         self.sex=sex
#         self.aggr=aggr
#         self.blood=blood
#     def dajia(self,dog):
#         print('%s打了%s一拳'%(self.name,dog.name))
#         dog.blood-=self.aggr
#         print(dog.blood)
# class Dog:
#     def __init__(self,name,aggr,blood):
#         self.name=name
#         self.aggr=aggr
#         self.blood=blood
#     def yao(self,person):
#         print('%s咬了%s一口'%(self.name,person.name))
#         person.blood-=self.aggr
#         print(person.blood)
# class Wuqi:
#     def __init__(self,wuqi_name,aggr,xi_blood):
#         self.wuqi_name=wuqi_name
#         self.aggr=aggr
#         self.xi_blood=xi_blood
#     def gongji(self,dog,person):
#         dog.blood-=self.aggr
#         person.blood+=self.xi_blood
# egon=People('egon','nan',2000,100000)
# alex=Dog('alex',1,4000)
# fthj=Wuqi('fangtianhuaji',2000,2000)
# alex.yao(egon)
# egon.wuqi=fthj.gongji(alex,egon)
# egon.dajia(alex)
# print('KO') 

三 组合与重用性

软件重用的重要方式除了继承之外还有另外一种方式,即:组合

组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合

组合:什么有什么的关系,也是为了减少重复代码

其实早在3.5小节中我们就体会了组合的用法,比如一个英雄有一个装备

复制代码
 1 >>> class Equip: #武器装备类
 2 ...     def fire(self):
 3 ...         print('release Fire skill')
 4 ... 
 5 >>> class Riven: #英雄Riven的类,一个英雄需要有装备,因而需要组合Equip类
 6 ...     camp='Noxus'
 7 ...     def __init__(self,nickname):
 8 ...         self.nickname=nickname
 9 ...         self.equip=Equip() #用Equip类产生一个装备,赋值给实例的equip属性
10 ... 
11 >>> r1=Riven('锐雯雯')
12 >>> r1.equip.fire() #可以使用组合的类产生的对象所持有的方法
13 release Fire skill
复制代码

组合与继承都是有效地利用已有类的资源的重要方式。但是二者的概念和使用场景皆不同,

1.继承的方式

通过继承建立了派生类与基类之间的关系,它是一种'是'的关系,比如白马是马,人是动物。

当类之间有很多相同的功能,提取这些共同的功能做成基类,用继承比较好,比如教授是老师

复制代码
 1 >>> class Teacher:
 2 ...     def __init__(self,name,gender):
 3 ...         self.name=name
 4 ...         self.gender=gender
 5 ...     def teach(self):
 6 ...         print('teaching')
 7 ... 
 8 >>> 
 9 >>> class Professor(Teacher):
10 ...     pass
11 ... 
12 >>> p1=Professor('egon','male')
13 >>> p1.teach()
14 teaching
复制代码

用组合的方式建立了类与组合的类之间的关系,它是一种‘有’的关系,比如教授有生日,教授教python课程

复制代码
 1 class People:
 2 #     def __init__(self,name,age,year,mon,day):
 3 #         self.name=name
 4 #         self.age=age
 5 #         self.birth=Date(year,mon,day)
 6 #     def walk(self):
 7 #         print('%s is walking' %self.name)
 8 # class Date:
 9 #     def __init__(self,year,mon,day):
10 #         self.year=year
11 #         self.mon=mon
12 #         self.day=day
13 #     def tell_birth(self):
14 #         print("出生于<%s>年 <%s>月 <%s>日"%(self.year,self.mon,self.day))
15 #
16 # class Student(People):
17 #     def __init__(self,name,age,year,mon,day,group):
18 #         People.__init__(self,name,age,year,mon,day)
19 #         self.group=group
20 #     def study(self):
21 #         print('%s is studying' %self.name)
22 #
23 # class Teacher(People):
24 #     def __init__(self,name,age,year,mon,day,level,salary):
25 #         People.__init__(self,name,age,year,mon,day)
26 #         self.level=level
27 #         self.salsry=salary
28 #     def teach(self):
29 #         print('%s is teaching' %self.name)
30 #
31 # t=Teacher('egon',18,1990,2,33)
32 # print(t.name,t.age)
33 # print(t.birth)
34 # print(t.birth.year)
35 # print(t.birth.mon)
36 # print(t.birth.day)
37 #
38 #
39 #
40 # t=Student('fang',18,1990,2,25)
41 # print(t.name,t.age)
42 # print(t.birth)
43 # print(t.birth.year)
44 # print(t.birth.mon)
45 # print(t.birth.day)
复制代码

当类之间有显著不同,并且较小的类是较大的类所需要的组件时,用组合比较好

 

3 关于对象的属性:对象的属性只存在于对象的命名空间,          只能被对象来调用和修改,如果类来调用或修改就会报错。

原文地址:https://www.cnblogs.com/fangjie0410/p/7527086.html