一、组合
1.1 什么是组合
对象的某个属性,事另一个对象,即对象中包着对象。
class Fo:
pass
class Bar:
pass
f.Fo()
f.bar = Bar()
1.2 为什么使用组合
可以减少代码冗余。
class Person:
school = 'oldboy'
class Teacher(Person):
def __init__(self,name,age,level,course_name,course_price,course_period):
self.name=name
self.age=age
self.level=level
class Student(Person):
def __init__(self,name,age,course,course_name,course_price,course_period):
self.name=name
self.age=age
self.course=course
class Person:
school = 'oldboy'
class Teacher(Person):
def __init__(self,name,age,level,course):
self.name=name
self.age=age
self.level=level
#course是课程对象,表示老师教授的课程
self.course=course
class Student(Person):
def __init__(self,name,age,course):
self.name=name
self.age=age
# course是课程对象,表示学生选的课程
self.course = course
class Course:
def __init__(self,course_name,course_price,course_period):
self.name=course_name
self.price=course_price
self.period=course_period
1.3 组合与继承
组合与继承都是有效地利用已有类的资源的重要方式。但是二者的概念和使用场景皆不同。
1.继承的方式
通过继承建立了派生类与基类之间的关系,它是一种'是'的关系,比如白马是马,人是动物。当类之间有很多相同的功能,提取这些共同的功能做成基类,用继承比较好,比如老师是人,学生是人
2.组合的方式
用组合的方式建立了类与组合的类之间的关系,它是一种‘有’的关系,比如教授有生日,教授教python和linux课程,教授有学生s1、s2、s3...
总结就是同一类关系使用组合,而拥有包含关系使用继承。
二、多态与多态性
2.1 什么是多态
多态:一类事物的多种形态。
多态性:多态性是指在不考虑实例类型的情况下使用实例
2.2 多态的好处
1.增加了程序的灵活性
2.增加了程序的而扩展性
class Animal:
def speak(self):
pass
class Pig(Animal):
def speak(self):
print('哼哼哼')
class Dog(Animal):
def speak(self):
print('汪汪')
class People(Animal):
def speak(self):
print('say hello')
pig=Pig()
dog=Dog()
people=People()
pig.speak()
dog.speak()
people.speak()
def animal_speak(obj):
obj.speak()
animal_speak(pig)
animal_speak(people)
因为python崇尚自由和随意,这样就让编程有更大的灵活性,但是这会给开发带来很多不便。因此我们需要约束方式;来避免这些情况的发生。
1.用abc实现接口统一化,约束代码(用的比较少)。
import abc
#第一在括号中写metaclass=abc.ABCMeta
class Animal(metaclass=abc.ABCMeta):
#第二在要约束的方法上,写abc.abstractmethod装饰器
@abc.abstractmethod
def speak(self):
pass
class Pig(Animal):
def speak(self):
print('哼哼哼')
使用abc,方法必须与abc.abstractmethod装饰器规定的方法一致(speak),否则会报错。
- 用异常处理来实现(常用)
class Animal():
def speak(self):
#主动抛出异常
raise Exception('你得给我重写它啊')
class Pig(Animal):
def speak(self):
print('哼哼哼')
class People(Animal):
def speak(self):
print('say hello')
pig=Pig()
pe=People()
def animal_speak(obj):
obj.speak()
animal_speak(pig)
animal_speak(pe)
使用异常处理的方式,可以对代码进行约束,当出现符合规矩的代码时,会报异常,结束代码,提醒更改。
3.崇尚鸭子类型(人为约束)
只要走路像鸭子(对象中有某个绑定方法),那你就是鸭子。
class Pig:
def speak(self):
print('哼哼哼')
class People:
def speak(self):
print('say hello')
pig=Pig()
pe=People()
def animal_speak(obj):
obj.speak()
animal_speak(pig)
animal_speak(pe)
三、封装
3.1什么是封装
封装就是将一系列有某种用途的程序,打包封好的过程,但是封装并不等同于隐藏。
3.2 如何实现代码隐藏
隐藏属性/隐藏方法 隐藏之后,外部访问不到,只有内部能够访问。
隐藏属性:通过 __变量名来隐藏。
#name 隐藏起来
class Person:
def __init__(self,name,age):
self.__name=name
self.__age=age
def get_name(self):
# print(self.__name)
return self.__name
隐藏方法:通过 __方法名来隐藏。
class Person:
def __init__(self,name,age):
self.__name=name
self.__age=age
def __speak(self):
print('6666')
隐藏属性是为了安全,隐藏方法是为了隔离复杂度。
但实际上隐藏的属性是由办法访问到的。
print(p.__dict__) #查找属性
print(p._Person__name)
3.3 property的用法
property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值。换而言之property是一种装饰器,把方法包装成数据属性。
class Person:
def __init__(self,name,height,weight):
self.name=name
self.height=height
self.weight=weight
@property
def bmi(self):
return self.weight/(self.height**2)
# return self.weight/(self.height*self.height)
p=Person(,,,)
# print(p.bmi())
print(p.bmi)