python开发面向对象基础:组合&继承

一,组合

组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合      人类装备了武器类就是组合

1.圆环,将圆类实例后传给圆环类

 1 #!/usr/bin/env python
 2 #_*_coding:utf-8_*_
 3 
 4 #circle,圆类
 5 from math import pi
 6 class Circle:
 7     def __init__(self,radius):
 8         self.radius = radius
 9     def perimeter(self):
10         return 2 * pi * self.radius
11     def area(self):
12         return pi * self.radius **2
13 
14 # c1 = Circle(10)
15 # print(c2.area())
16 
17 #圆环(不判断半径版本),就是圆的组合,利用了上面圆的类
18 class Ring:
19     def __init__(self,outside_radius,inside_radius):
20         self.outside_circle = Circle(outside_radius)   #实例化一个圆形,作为self.outside_circle属性的值
21         self.inside_circle = Circle(inside_radius)     #再实例化一个圆形
22     def area(self):
23         return self.outside_circle.area() - self.inside_circle.area()
24     def perimeter(self):
25         return self.inside_circle.perimeter() + self.outside_circle.perimeter()
26 
27 # r1 = Ring(20,10)     #这是傻瓜版本,没有考虑谁的半径大,谁是外圈内圈
28 # print(r1.area())
29 # print(r1.perimeter())
30 
31 #圆环(判断半径版本)
32 class Ring:
33     def __init__(self,outside_radius,inside_radius):
34         outside_r = max(outside_radius,inside_radius)   #判断谁大谁是外环
35         inside_r = min(outside_radius,inside_radius)    #
36         self.outside_circle = Circle(outside_r)   #实例化一个圆形,作为self.outside_circle属性的值
37         self.inside_circle = Circle(inside_r)     #再实例化一个圆形
38     def area(self):
39         return self.outside_circle.area() - self.inside_circle.area()
40     def perimeter(self):
41         return self.inside_circle.perimeter() + self.outside_circle.perimeter()
42 
43 # 将判断在实例化的时候判断
44 # outer = input('外半径:')
45 # inner = input('内半径:')
46 # if outer.isdigit() and inner.isdigit() and int(outer) > int(inner):
47 #     r1 = Ring(int(outer),int(inner))
48 #     print(r1.perimeter())
49 #     print(r1.area())
50 
51 # 将判断给类方法里面去判断
52 # r1 = Ring(20,10)
53 # print(r1.area())
54 # print(r1.perimeter())

 

二,.多组合

 1 #!/usr/bin/env python
 2 #_*_coding:utf-8_*_
 3 
 4 # 老师 课程 生日
 5 # 第一种组合,在里面组合
 6 class Teacher:
 7     def __init__(self,name,salary,friend,course_name,course_period,course_price):
 8         self.name = name
 9         self.salary = salary
10         self.bf = friend
11         self.course = Course(course_name,course_period,course_price)   #这里实例化Course
12 
13 class Course:
14     def __init__(self,name,period,price):
15         self.name = name
16         self.period = period
17         self.price = price
18 
19 egg = Teacher('egon',200,'yuan','python','6months',20000)  #传入老师,课程的属性
20 print(egg.bf)
21 print(egg.course.name)     # egg.course就是Course的实例,相当于python
22 
23 # 第二种组合,在外面组合将课程先实例化后传入,适用于共性一样的
24 class Teacher:
25     def __init__(self, name, salary, friend, python):
26         self.name = name
27         self.salary = salary
28         self.bf = friend
29         self.course = python
30 
31 class Course:
32     def __init__(self, name, period, price):
33         self.name = name
34         self.period = period
35         self.price = price
36 
37 python = Course('python', '6months', 20000)
38 #将python课程实例写这里,那么所有教Python的老师都可以这么写
39 egg = Teacher('egon', 200, 'yuan', python)    #Python实例化后传入,就不需要每次传入很多参数,较少内存
40 print(egg.bf)
41 print(egg.course.name)
42 
43 # 第三种组合,在外面组合,适用于每个人都有的,但是又不一样的
44 class Teacher:
45     def __init__(self,name,salary,friend,python):
46         self.name = name
47         self.salary = salary
48         self.bf = friend
49         self.course = python
50 
51 class Birth:
52     def __init__(self,year,month,day):
53         self.year = year
54         self.month = month
55         self.day = day
56 
57 # egg = Teacher('egon', 200, 'yuan', 'python')
58 # egg_birth = Birth(1965,2,2)
59 # print(egg_birth.year)
60 # 将整个生日类的东西给了交给了egg的birth,可以调用所有属性和方法
61 # 如果写在老师类里面,那就太多了属性,代码就不易读
62 # 重新定个新类,然后绑定给老师
63 # egg.birth = egg_birth
64 # print(egg.birth.year)

 

三,继承

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

 1 #!/usr/bin/env python
 2 #_*_coding:utf-8_*_
 3 
 4 # 子类会继承父类的所有属性和方法
 5 class Animal:      #父类  基类  超类
 6     def __init__(self,name,life_value,aggr):
 7         self.name = name
 8         self.life_value = life_value
 9         self.aggr = aggr
10 
11 class Person(Animal):  #子类  派生类
12     pass
13 
14 class Dog(Animal): #子类  派生类
15     pass
16 
17 egg = Person('egon',1000,50)
18 print(egg.name)
19 print(egg.aggr)
20 
21 # class Dad:pass
22 # class Ma:pass
23 # class Son1(Dad,Ma):pass    多继承
24 # class Son2(Dad):pass
25 
26 # print(Son1.__bases__)    __bases__查看父类
27 # print(Son2.__bases__)
28 # print(Dad.__bases__)     --obj是所有类的鼻祖

 

3.1 继承与抽象

先抽象,在继承

抽象分成两个层次: 

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

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

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

 

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

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

 

3.2 经典类与新式类

 1 #!/usr/bin/env python
 2 #_*_coding:utf-8_*_
 3 
 4 #python2
 5 #class Dad:         #经典类  这个是不会集成obj的类
 6 #class Dag(object)  #新式类
 7 
 8 #python3
 9 #不存在经典类
10 #class Dad  ==  class Dag(object) #新式类

 

四,派生

当然子类也可以添加自己新的属性或者在自己这里重新定义这些属性(不会影响到父类),需要注意的是,一旦重新定义了自己的属性且与父类重名,那么调用新增的属性时,就以自己为准了。

  1 #!/usr/bin/env python
  2 #_*_coding:utf-8_*_
  3 
  4 #继承
  5 class Pet:
  6     def eat(self):
  7         pass
  8     def sleep(self):
  9         pass
 10     def drink(self):
 11         pass
 12 
 13 class Cat(Pet):            #Pet类的一个派生类,也叫子类
 14     def catch(self):pass   #Pet类的一个派生方法
 15 
 16 class Dog(Pet):
 17     def watch_door(self):pass
 18 
 19 # 中华气死猫 = Cat()
 20 # 中华气死猫.catch()
 21 # 中华气死猫.eat()
 22 
 23 #1.人狗大战继承版本
 24 class Animal:      #父类  基类  超类
 25     def __init__(self,name,life_value,aggr):
 26         self.name = name
 27         self.life_value = life_value
 28         self.aggr = aggr  #攻击力
 29     def eat(self):
 30         self.life_value += 10
 31 
 32 class Person(Animal):  #子类  派生类
 33     def attack(self,enemy):    #人的派生方法
 34         enemy.life_value -= self.aggr
 35 
 36 class Dog(Animal): #子类  派生类
 37     def bite(self,person):   #狗的派生方法
 38         person.life_value -= self.aggr
 39 
 40 # egg = Person('gon',100,10)
 41 # dahei = Dog('dahei',200,20)
 42 # print(dahei.life_value)
 43 # dahei.eat()
 44 # print(dahei.life_value)
 45 # print(egg.life_value)
 46 # dahei.bite(egg)
 47 # print(egg.life_value)
 48 
 49 
 50 #2.如果属性多,增加对象属性,又要用父类的又要用自己的
 51 class Animal:      #父类  基类  超类
 52     def __init__(self,name,life_value,aggr):
 53         self.name = name
 54         self.life_value = life_value
 55         self.aggr = aggr  #攻击力
 56     def eat(self):
 57         self.life_value += 10
 58 
 59 class Person(Animal):  #子类  派生类
 60     def __init__(self,money):
 61         self.money = money   #派生属性
 62     def attack(self,enemy):    #人的派生方法
 63         enemy.life_value -= self.aggr
 64 
 65 class Dog(Animal): #子类  派生类
 66     def __init__(self,breed):
 67         self.breed = breed
 68     def bite(self,person):   #狗的派生方法
 69         person.life_value -= self.aggr
 70 
 71 # ha2 = Dog('牛头梗',20000,100)
 72 # 报错 _ __init__() takes 2 positional arguments but 4 were given
 73 # 在继承中,如果子类有的方法就执行子类的,如果没有执行父类的
 74 # 本例中子类有自己的Init方法,需要2个参数,加上self算一个,当然这个不需要传
 75 
 76 #3.有父类的对象属性,又有子类的属性,super方法来更改__init__
 77 class Animal:      #父类  基类  超类
 78     def __init__(self,name,life_value,aggr):
 79         self.name = name
 80         self.life_value = life_value
 81         self.aggr = aggr  #攻击力
 82     def eat(self):
 83         self.life_value += 10
 84 
 85 class Person(Animal):  #子类  派生类
 86     def __init__(self,money,name,life_value,aggr):
 87         super().__init__(name,life_value,aggr)
 88         self.money = money   #派生属性
 89 
 90     def attack(self,enemy):    #人的派生方法
 91         enemy.life_value -= self.aggr
 92 
 93 class Dog(Animal): #子类  派生类
 94     def __init__(self,breed,name,life_value,aggr):
 95         # Animal.__init__(self,name,life_value,aggr)        #让子类执行父类的方法,就是父类名.方法名(参数),连self也得传(经典类的继承)
 96         super().__init__(name,life_value,aggr)          #super关键字——新式类,跟上面的经典类效果一样
 97         # super(Dog,self).__init__(name,life_value,aggr)  #super关键字关键字——新式类解释上面的写法跟经典类一样,只是简化了
 98         self.breed = breed
 99     def bite(self,person):   #狗的派生方法
100         person.life_value -= self.aggr
101 
102 # dahei = Dog('狼','dahei',2000,100)
103 # print(dahei.life_value)
104 
105 
106 #4.有父类的对象属性,又有子类的属性,super方法
107 class Animal:      #父类  基类  超类
108     def __init__(self,name,life_value,aggr):
109         self.name = name
110         self.life_value = life_value
111         self.aggr = aggr  #攻击力
112     def eat(self):
113         self.life_value += 10
114 
115 class Person(Animal):  #子类  派生类
116     def __init__(self,money,name,life_value,aggr):
117         super().__init__(name,life_value,aggr)   #
118         self.money = money   #派生属性
119 
120     def attack(self,enemy):    #人的派生方法
121         enemy.life_value -= self.aggr
122 
123 class Dog(Animal): #子类  派生类
124     def __init__(self,breed,name,life_value,aggr):
125         #Animal.__init__(self,name,life_value,aggr)   #让子类执行父类的方法,就是父类名.方法名(参数),连self也得传
126         super().__init__(name,life_value,aggr)  #super关键字——新式类
127         #super(Dog,self).__init__(name,life_value,aggr)  #super关键字关键字——新式类
128         self.breed = breed
129     def bite(self,person):   #狗的派生方法
130         person.life_value -= self.aggr
131 
132     def eat(self):       # 父类方法的重写
133         super().eat()     #子类执行父类的eat方法,如果没有的话,就会执行下面代码,也可以在外面引用
134         print('dog is eating~~~ ')
135 
136 dahei = Dog('', 'dahei', 2000, 100)
137 print(dahei.life_value)
138 dahei.eat()
139 super(Dog,dahei).eat()   #父类方法的重写,在外面引用父类的方法,dahei就是self
140 print(dahei.life_value)
141 
142 # 父类方法的重写不推荐用,因为这样还不如直接改了父类

 

posted @ 2017-08-12 23:40  liqianlong  阅读(304)  评论(0编辑  收藏  举报