python--组合与继承

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

表示的是:什么有什么的关系。

为什么会用到组合:

  独立的对象不能发挥他的作用,必须依赖一个对象

  eg:刀具有攻击的方法,需要用人去使用刀才能攻击 

class Person:
    def __init__(self,name,sex,hp,ad):
        self.name = name
        self.sex = sex
        self.hp = hp
        self.ad = ad
        self.money = 0#这里不能定义到静态属性,静态属性是被每一个对象公用的,个人钱,不能大家公用;定义到init方法里,就会跟着每一个对象

    def attack(self,d):
        d.hp -= self.ad
        print('%s攻击了%s,%s掉了%s点血' % (self.name, d.name, d.name, self.ad))
    def pay(self):
        money = int(input("请输入充值金额:"))
        self.money += money
        print('您的余额是:%s' % self.money)
    def wear(self,weapon):
        if self.money >= weapon.price:
            #武器类的对象作为人类对象的一个属性
            self.weapon = weapon    #组合给人装备了武器
            self.money -= weapon.price
            print("购买成功,已装备了%s" %(weapon.name))
        else:
            print("余额不足,请先充值")
    def attack_with_weapon(self,dog):
        if "weapon" in self.__dict__:
            self.weapon.skill(dog)
        else:
            print("请先装备武器")

class Dog:
    def __init__(self, name, kind, hp, ad):
        self.name = name
        self.kind = kind
        self.hp = hp
        self.ad = ad
    def bite(self, p):
        p.hp -= self.ad
        print('%s咬了%s一口,%s掉了%s点血' % (self.name, p.name, p.name, self.ad))
class Weapon:
    def __init__(self,name,price,ad,level):
        self.name = name
        self.price = price
        self.level = level
        self.ad = ad * self.level
    def skill(self,dog):
        dog.hp -= self.ad
        print('%s受到了%s的伤害,%s掉了%s点血' % (dog.name, self.name, dog.name, self.ad))

alex = Person("大王","",100,10)
jinmao = Dog("小金","金毛",150,50)
nief = Weapon("",1000,100,1)

# alex.pay()
# alex.wear(nief)
# print(alex.__dict__)
# print(alex.weapon)  #<__main__.Weapon object at 0x0000000001134828>
# print(nief) #<__main__.Weapon object at 0x0000000001134828>
#nief和weapon是一个内存地址
# nief.skill(jinmao)
# alex.weapon.skill(jinmao)

li = ['攻击','充值','装备武器','使用武器攻击']
while True:
    for i,k in enumerate(li,1):
        print(i,k)
    num = input(">>>想选择操作序号")
    if num == "1":
        alex.attack(jinmao)
    elif num == "2":
        alex.pay()
    elif num == "3":
        print('装备前余额 %s'%alex.money)
        alex.wear(nief)
        print('装备后余额 %s' % alex.money)
    elif num == "4":
        alex.attack_with_weapon(jinmao)
    else:
        print('无效的序号')    
人带武器,攻击狗

什么时候用到组合:

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

 组合的两种方式:

        1.在__init__方法里面组合。

1 class BirthDate:
 2     def __init__(self,year,month,day):
 3         self.year=year
 4         self.month = month
 5         self.day = day
 6 class Course:
 7     def __init__(self,name,price,period): #period为周期
 8         self.name =name
 9         self.price = price
10         self.period = period
11 class Teacher:
12     def __init__(self,name,salary,year,month,day,price,period): #那么这个里面也要把该有的属性传进去
13         self.birth = BirthDate(year,month,day) #在里面组合(将BirthDate里面有的属性传入进去)
14         self.course=Course(name,price,period)
15         self.name = name
16         self.salary = salary
17 # 实例化方法一:
18 egg = Teacher('egon',2000,1999,12,2,'19800','6 months')  #也要实例化,Teacher类里面的属性都得实例化
19 print(egg.birth.month)  #当然老师也有生日,就让egg.birth.month
20 print(egg.course.period)
21 
22 # 实例化方法二:
23 egg.birth=BirthDate(1996,22,4)
24 print(egg.birth.month)
在__init__里面组合

         2.在外面组合。

1 class BirthDate:
 2     def __init__(self,year,month,day):
 3         self.year=year
 4         self.month = month
 5         self.day = day
 6 class Course:
 7     def __init__(self,name,price,period): #period为周期
 8         self.name =name
 9         self.price = price
10         self.period = period
11 class Teacher:
12     def __init__(self,name,salary,course):
13         self.name = name
14         self.salary = salary
15         self.course = course
16 #
17 # #在外面组合。(组合就是一个类的属性是另一个类的对象)
18 
19 egg = Teacher('egon',2000,'python')
20 egg.birth=BirthDate(1996,22,4) #直接给egg一个birth的属性,
21 print(egg.birth.year)
22 
23 egg.course =Course('python',19800,'6 months',)
24 print(egg.course.period)
在类外面实例化组合

总结:

  把一个对象1,赋值给另一个对象2的属性(self.weapon = nife)

然后通过被赋值对象2.对象.方法(这个方法指的是对象1的方法),就可以直接来使用对象1里的方法。

二、继承:

  1.继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类。

继承又分为单继承和多继承:

class ParentClass1: #定义父类
    pass

class ParentClass2: #定义父类
    pass

class SubClass1(ParentClass1): #单继承,基类是ParentClass1,派生类是SubClass1
    pass

class SubClass2(ParentClass1,ParentClass2): #python支持多继承,用逗号分隔开多个继承的类
    pass

  2.查看所有继承的父类

print(Person.__bases__)      #__base __只查看从左到右继承的第一个子类,__bases__则是查看所有继承的父类

如果没有指定父类,python会默认继承object类,object是所有python的父类。

 

经典类:在python2中,class Dad: 不会继承object,这样的类叫做经典类(它叫经典类,不是因为它经典,而是因为它比较老)

新式类:在python3中,python会默认继承object类(一切皆对象)

    class Dad  就相当于python2中的  class Dad(object)  #新式类

而且python3中没有经典类了

  3.继承中的init

  4.继承中的派生方法

  5.继承父类的方法:自己本类没有同名方法

  6.对象使用名字的循序:先找对象自己内存空间中的,在找自己类中的,再找父类中。

  7.self.  名字的时候,不要看self当前在哪个类里,要看这个self到底是谁的对象。

面试题

class Parent:
    def func(self):
        print("in parent func")
    def __init__(self):
        self.func()
        #print(id(self))
class Son(Parent):
    def func(self):
        print("in Son func")
s = Son()

分析结果:(总结出:对象可以找到类,类不能找对象,都是单项寻找。)

 

继承中的私有方法分析:

 

 

 

posted @ 2018-04-13 15:10  纸上得来终觉浅,  阅读(249)  评论(0)    收藏  举报