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 # 父类方法的重写不推荐用,因为这样还不如直接改了父类