面向编程(二)继承

一.基础

 

 1 class Garen:
 2     camp='Demacia'
 3     n=0
 4     hobby=[]        #类的变量一般定义成不可变的
 5     def __init__(self,nickname,aggressivity=58,life_value=455):
 6         self.nickname=nickname           #为自己的盖伦起了个别名
 7         self.aggressivity=aggressivity
 8         self.life_value=life_value
 9         Garen.n+=1                #类.n  对象每产生一个名字(统计实例化次数)
10         #self.hobby=[]
11     def attack(self,enemy):
12         enemy.life_value-=self.aggressivity
13 
14 g1=Garen('草丛伦')
15 g2=Garen('草丛伦2')
16 g3=Garen('草丛伦3')
17 print(g1.hobby,id(g1.hobby))
18 print(g2.hobby,id(g2.hobby))
19 print(g3.hobby,id(g3.hobby))
20 print(g1.n)          #
21 print(g3.n)
22 
23 
24 
25 
26 
27 [] 13837768               #指向同一个列表,同一个内存地址
28 [] 13837768
29 [] 13837768
30 3
31 3

 

 

 

 

 

 1 g1.hobby.append('g1 hobby')
 2 g2.hobby.append('g2 hobby')
 3 g3.hobby.append('g3 hobby')
 4 print(g1.hobby)
 5 g1.camp='12123'
 6 print(g1.camp)
 7 
 8 
 9 
10 ['g1 hobby', 'g2 hobby', 'g3 hobby']    #可变类型
11 12123                     #不可变类型

 

 

 1 class Garen:
 2     camp='Demacia'
 3     n=0
 4     #hobby=[]        #类的变量一般定义成不可变的
 5     def __init__(self,nickname,aggressivity=58,life_value=455):
 6         self.nickname=nickname           #为自己的盖伦起了个别名
 7         self.aggressivity=aggressivity
 8         self.life_value=life_value
 9         Garen.n+=1                #类.n  对象每产生一个名字(统计实例化次数)
10         self.hobby=[]       #定义在自己里面,别的实例进不来
11     def attack(self,enemy):
12         enemy.life_value-=self.aggressivity
13 g1=Garen('草丛伦')
14 g2=Garen('草丛伦2')
15 g3=Garen('草丛伦3')
16 
17 
18 g1.hobby.append('g1 hobby')
19 g2.hobby.append('g2 hobby')
20 g3.hobby.append('g3 hobby')
21 print(g1.hobby)
22 
23 
24 
25 
26 
27 ['g1 hobby']

 

 1 class Garen:
 2     camp='Demacia'
 3     n=0
 4     #hobby=[]        #类的变量一般定义成不可变的
 5     def __init__(self,nickname,aggressivity=58,life_value=455):
 6         self.nickname=nickname           #为自己的盖伦起了个别名
 7         self.aggressivity=aggressivity
 8         self.life_value=life_value
 9         Garen.n+=1                #类.n  对象每产生一个名字(统计实例化次数)
10         self.hobby=[]       #定义在自己里面,别的实例进不来
11     def attack(self,enemy):
12         print('=====>')
13         enemy.life_value-=self.aggressivity
14 
15 g1=Garen('草丛伦')
16 g2=Garen('草丛伦2')
17 # print(g1.hobby,id(g1.hobby))
18 # print(g2.hobby,id(g2.hobby))
19 # print(g3.hobby,id(g3.hobby))
20 # print(g1.n)          #
21 # print(g3.n)
22 print(g1.attack)
23 print(Garen.attack)
24 g1.attack(g2)            #绑定方法指向函数的功能,就是绑定到每个对象身上的
25                         #对象调绑定方法操作的就是对象自己,Garen.attack(g1,g2) g2为位置参数
26 #其实就相当于Gaven.attack(g1,g2)
27 #区别:可以把对象自己当成参数传进去

 

二.继承

1.什么是继承

  继承是一种创建新的类的方法,在python中,新建的类可以继承自一个或者多个父类,原始类称为基类或超类,新建的类称为派生类或子类。

  分为: 单继承和多继承

 1 class ParentClass1:    #定义父类
 2     pass
 3 class ParentClass2:    #定义父类
 4     pass
 5 class SubClass1(ParentClass1): #单继承,基类是ParentClass1,派生类是SubClass
 6     pass
 7 class SubClass2(ParentClass1,ParentClass2):  #多继承,用逗号分隔开多个继承的类
 8     pass

73 
74 print(SubClass1.__bases__)
75 print(SubClass2.__bases__)
76 print(ParentClass1.__bases__)           #python的类默认继承object类,object是所有python类的基类,它提供一些常见方法如(_str_)实现
77 
78 
79 
80 (<class '__main__.ParentClass1'>,)
81 (<class '__main__.ParentClass1'>, <class '__main__.ParentClass2'>)
82 (<class 'object'>,)

 

抽象即抽取类似或者说比较像的部分。

抽象分成两个层次: 

1.将奥巴马和梅西这俩对象比较像的部分抽取成类; 

2.将人,猪,狗这三个类比较像的部分抽取成父类。

抽象最主要的作用是划分类别(可以隔离关注点,降低复杂度)

 

继承:是基于抽象的结果,通过编程语言去实现它,肯定是先经历抽象这个过程,才能通过继承的方式去表达出抽象的结构。

抽象只是分析和设计的过程中,一个动作或者说一种技巧,通过抽象可以得到类

 

 

 1 class Hero:
 2     def __init__(self,nickname,aggressivity,life_value):
 3         self.nickname=nickname
 4         self.aggressivity=aggressivity
 5         self.life_value=life_value
 6 
 7     def move_forward(self):
 8         print('%s move forward' %self.nickname)
 9 
10     def move_backward(self):
11         print('%s move backward' %self.nickname)
12 
13     def move_left(self):
14         print('%s move forward' %self.nickname)
15 
16     def move_right(self):
17         print('%s move forward' %self.nickname)
18 
19     def attack(self,enemy):
20         enemy.life_value-=self.aggressivity
21 class Garen(Hero):
22     pass
23 
24 class Riven(Hero):
25     pass
26 
27 g1=Garen('草丛伦',100,300)
28 r1=Riven('锐雯雯',57,200)
29 
30 print(g1.life_value)
31 r1.attack(g1)
32 print(g1.life_value)
33 
34 '''
35 运行结果
36 300
37 243
38 '''

 

2.派生

 

如果在子类中定义与父类相同的,走子类中的。也可以定义一个新的。
 1 class Hero:
 2     def __init__(self,nickname,
 3                  aggressivity,
 4                  life_value):
 5         self.nickname = nickname
 6         self.aggressivity = aggressivity
 7         self.life_value = life_value
 8 
 9     def attack(self,enemy):
10         enemy.life_value -= self.aggressivity
11 
12 
13 class Garen(Hero):
14     camp='Demacia'
15     def attack(self,enemy):
16         print('from garen attack')        #如果在子类中定义与父类相同的,走子类中的
17     def fire(self):
18         print('%s is fireing' %self.nickname)
19 
20 class Riven(Hero):
21     camp='Noxus'
22 
23 g1=Garen('garen',18,200)
24 r1=Riven('rivren',18,200)
25 g1.attack(r1)
26 print(g1.camp)
27 print(r1.camp)

 

 1.重用

 

 1 class Hero:
 2     def __init__(self,nickname,
 3                  aggressivity,
 4                  life_value):
 5         self.nickname = nickname
 6         self.aggressivity = aggressivity
 7         self.life_value = life_value
 8 
 9     def attack(self,enemy):   5.
10         print('Hero attack')
11         enemy.life_value -= self.aggressivity
12 class Garen(Hero):
13     camp='Demacia'
14     def attack(self,enemy):     # 3.指向类的函数 self=g1,enemy=r1
15         Hero.attack(self,enemy)     #重用父类的 4
16         print('from garen attack')        #如果在子类中定义与父类相同的,走子类中的
17     def fire(self):
18         print('%s is fireing' %self.nickname)
19 
20 class Riven(Hero):
21     camp='Noxus'
22 
23 g1=Garen('garen',18,200)  #  1.g1的名称空间
24 r1=Riven('rivren',18,200)
25 g1.attack(r1)      # 2.g1的绑定方法  不用传参数,实际传的g1和r1
26 
27 
28 Hero attack
29 from garen attack

 

 

 

 1 class Hero:
 2     def __init__(self,nickname,
 3                  aggressivity,
 4                  life_value):
 5         self.nickname = nickname
 6         self.aggressivity = aggressivity
 7         self.life_value = life_value
 8 
 9     def attack(self,enemy):
10         print('Hero attack')
11         enemy.life_value -= self.aggressivity
12 class Garen(Hero):
13     camp='Demacia'
14     def __init__(self,nickname,aggressivity,life_value,script):       ##
15         Hero.__init__(self,nickname,aggressivity,life_value)  ##调用父类功能
16         self.script = script   #新属性
17     def attack(self,enemy):  #self=g1,enemy=r1 #在这里定义新的attack,不再使用父类的attack,且不会影响父类
18         Hero.attack(self,enemy)     #重用父类的
19         print('from garen attack')        #如果在子类中定义与父类相同的,走子类中的
20     def fire(self):
21         print('%s is fireing' %self.nickname)
22 
23 class Riven(Hero):
24     camp='Noxus'
25 
26 g1=Garen('garen',18,200,'人在塔下') #Garen.__init__(g1,'garen',18,200,'人在塔下')

 

2.组合

 

 

 1 class Teacher:
 2     def __init__(self,name,sex,course):
 3         self.name=name
 4         self.sex=sex
 5         self.course=course
 6 
 7 class Student:
 8     def __init__(self,name,sex,course):
 9         self.name=name
10         self.sex=sex
11         self.course=course
12 
13 class Course:
14     def __init__(self,name,price,period):
15         self.name=name
16         self.price=price
17         self.period=period
18 
19 python_obj=Course('python',15800,'7m')
20 t1=Teacher('egon','male',python_obj)
21 s1=Student('cobila','male',python_obj)
  print(s1.course.name)
  print(t1.course.name)

 

继承: 类与类之间是的关系,完成代码重用   (人和狗都是动物)

组合:类与类之间有的关系,(老师,学生与生日    老师,学生与课程  学生与分数)

 

 

3.接口与归一化设计

 

继承

一::继承基类的方法,并做出自己的改变或者扩展(代码重用)

二:声明某个子类兼容于某基类,定义一个接口类Interface,接口类定义了一些接口名(就是函数名)

 

继承的第二种含义非常重要,它又叫接口继承。接口继承实质上是要求做一个良好的抽象,这个抽象规定了一个兼容接口,使得外部调用者无需关心具体细节,可一视同仁的处理时限了特定接口的所有对象——这在程序设计上,叫做归一化。

 

 

1.主动抛出异常

 

class Animal:
    def run(self):
        raise AttributeError('子类必须实现这个方法')
    def speak(self):
        raise AttributeError('子类必须实现这个方法')

class People(Animal):
    pass
    # def run(self):
    #     print('人正在走')
    # def speak(self):
    #     print('说话')

peo1=People()
peo1.run()





   raise AttributeError('子类必须实现这个方法')
AttributeError: 子类必须实现这个方法

  

2.抽象类

 

本质还是类,与普通类额外的特点是:加了装饰器的函数,子类必须实现他们。

普通类除了raise抛出异常没有其他方法限制子类必须实现

 1 import abc
 2 class Animal(metaclass=abc.ABCMeta):
 3     @abc.abstractmethod          #必须被子类实现run
 4     def run(self):
 5         pass
 6     @abc.abstractmethod          #必须被子类实现speak
 7     def speak(self):
 8         pass
 9 
10 
11 class People(Animal):
12     def run(self):
13         pass
14 
15     def speak(self):
16         pass
17 peo1=People()                   #做实例化时会报错

 

posted @ 2017-04-19 16:26  samyoung  阅读(177)  评论(0编辑  收藏  举报