类的特性::封装、继承、多态。 “一个接口,多种实现”css
一、类的封装
做用防止内部对象数据不能被外部随意修改;使外部程序不须要关注对象内部的构造,只须要经过对象对外提供的接口进行访问。可分为类的公有属性、私有属性。python
把功能实现的细节不对外暴露;linux
私有属性:(对外部是不可见的、对内部是可见的)
__private_attr_name = value
def get_heart(self) #对外部提供只读访问接口编程
return self.__heart
r1._Role__heart :强制访问私有属性ide
公有属性:
在类里面定义的方法,叫作公有属性 模块化
二、类的继承函数
1)、类的继承讲解ui
面向对象编程(OOP) 语言的一个主要功能就是“继承”。继承是指这样一种能力:它可使用现有类的全部功能,并在无需从新编写原来的类的状况下对这些功能进行扩展。使用继承时,有一点须要注意,那就是两个类之间的关系应该是“属于”关系。编码
定义:
一、经过继承建立的新类称为“子类”或“派生类”。
二、被继承的类称为“基类”、“父类”或“超类”。
三、继承的过程,就是从通常到特殊的过程。
要实现继承,能够经过“继承”(Inheritance)和“组合”(Composition)来实现。一个子类能够继承多个基类。可是通常状况下,一个子类只能有一个基类,要实现多重继承,能够经过多级继承来实现。(注意:建议最多就是三层。)url
继承概念的实现方式主要有2类:实现继承、接口继承。
一、实现继承是指使用基类的属性和方法而无需额外编码的能力;
二、接口继承是指仅使用属性和方法的名称、可是子类必须提供实现的能力(子类重构爹类方法);
面向对象编程开发范式大体为:划分对象→抽象类→将类组织成为层次化结构(继承和合成) →用类与实例进行设计和实现几个阶段。
举例:
A、简单例子类的继承:
class Person(object): #定义类 def talk(name): #类的调用方法 print("Who's Talking? It's me.-- %s " % name) class BlckPerson(Person): #简单的子类调用父类 pass b = BlckPerson b.talk("chen") #直接调用父类中的方法 输出: Who's Talking? It's me.-- chen
B、类继承中,父类与子类中 self 中参数传递:由子类中self 传参到 父类 中。
#conding:utf-8 class Person(object): #定义类 def __init__(self,name,age): self.name = name self.age = age self.other = "normal" def talk(self): #类的调用方法 print("Who's Talking? It's me.-- %s " % self.name) class BlckPerson(Person): #简单的子类调用父类 def __init__(self,name,age,height): Person.__init__(self,name,age) #把父类的公有属性,也定义继承过来。 self.height = height def size(self): print ("%s 身高是 %s" % (self.name,self.height)) b = BlckPerson('chen1203',25,'180cm') #调用类并传值。 b.talk() #直接调用父类中的方 b.size() #在子类中,没有定义self.name,继承父类后,能够直接调用 输出: Who's Talking? It's me.-- chen1203 chen1203 身高是 180cm
C、类的单继承示例(复杂度高点)
class SchoolMember(object): member = 0 '''定义共同类别''' def __init__(self,name,age,sex): self.name = name self.age = age self.sex = sex self.enroll() def enroll(self): '''注册''' print ("A New School Member Enrolled ,It's Name: %s" % self.name) SchoolMember.member += 1 def tell(self): '''打印信息''' print("----------%s-------" % self.name) for k,v in self.__dict__.items(): print(k,v) print("-----END-----") """ def __del__(self): #析构函数 '''开除学生''' print('开除[%s]' % self.name) self.member -= 1 """ class Tearcher(SchoolMember): '''老师''' def __init__(self,name,age,sex,salary,course): SchoolMember.__init__(self,name,age,sex) #经典类的调用 self.salary = salary self.course = course def Tearching(self): print("Teacher [%s] is tearching [%s] " % self.name,self.course) class Students(SchoolMember): '''' 学生''' def __init__(self,name,age,sex,course,fee): SchoolMember.__init__(self,name,age,sex) self.course = course self.fee = fee self.amount = 0 def pay_fee(self,amount): print('student [%s] has just paied [%s]' % (self.name, amount)) self.amount += amount T1 = Tearcher('chen1203',25,'M',2000,"PHP") T1.tell() S1 = Students('jianhui', 30, 'M', 'python', 3000) S1.tell() S2 = Students('huaming', 22, 'M', 'python', 1000) S2.tell() print(SchoolMember.member) 输出: A New School Member Enrolled ,It's Name: chen1203 ----------chen1203------- course PHP sex M salary 2000 name chen1203 age 25 -----END----- A New School Member Enrolled ,It's Name: jianhui ----------jianhui------- fee 30000 course python sex M amount 0 name jianhui age 30 -----END----- A New School Member Enrolled ,It's Name: huaming ----------huaming------- fee 1000 course python sex M amount 0 name huaming age 22 -----END----- 会员总数:3
D、类的多继承示例(用的很少,通常都是使用单继承)。有些语言可能不支持,但Python是支持的
接着跟上面的例子,举例以下:
class SchoolMember(object): member = 0 '''定义共同类别''' def __init__(self,name,age,sex): self.name = name self.age = age self.sex = sex self.enroll() def enroll(self): '''注册''' print ("A New School Member Enrolled ,It's Name: %s" % self.name) SchoolMember.member += 1 def tell(self): '''打印信息''' print("----------%s-------" % self.name) for k,v in self.__dict__.items(): print(k,v) print("-----END-----") """ def __del__(self): #析构函数 '''开除学生''' print('开除[%s]' % self.name) self.member -= 1 """ class School(object): def open_branch(self,addr): print ("Opening a new branch in ",addr) class Tearcher(SchoolMember,School): #把以上的两个类进行继承。主要在这个位置进行添加 '''老师''' def __init__(self,name,age,sex,salary,course): SchoolMember.__init__(self,name,age,sex) #经典类的调用 self.salary = salary self.course = course def Tearching(self): print("Teacher [%s] is tearching [%s] " % self.name,self.course) class Students(SchoolMember,School): '''' 学生''' def __init__(self,name,age,sex,course,fee): SchoolMember.__init__(self,name,age,sex) self.course = course self.fee = fee self.amount = 0 def pay_fee(self,amount): print('student [%s] has just paied [%s]' % (self.name, amount)) self.amount += amount T1 = Tearcher('chen1203',25,'M',2000,"PHP") S1 = Students('jianhui', 30, 'M', 'python', 30000) S2 = Students('huaming', 22, 'M', 'python', 1000) S1.open_branch("广州") 输出: A New School Member Enrolled ,It's Name: chen1203 A New School Member Enrolled ,It's Name: jianhui A New School Member Enrolled ,It's Name: huaming Opening a new branch in 广州
2)、新式类与经典类
注意:之后的使用中,最好统一使用新式类,调用也是用super的方法
新式类与经典类的区别
语法区别:(新的写法中,都是会按照新式类的写法来走)
class Persion(object): #新式类
class Persion: #经典类
调用方法的区别:(针对类的多继承中的例子)
SchoolMember.__init__(self,name,age,sex)#经典类的调用
super(Tearcher,self).__init__(name,age,sex) #新式类的调用
继承搜索的顺序发生了改变:
@ 经典类多继承属性搜索顺序: 先深刻继承树左侧,再返回,开始找右侧;
@ 新式类多继承属性搜索顺序: 先水平搜索,而后再向上移动
A、新式类与经典类的区别:新式类对象能够直接经过__class__属性获取自身类型:type
举例:
"""python 3 中执行""" # -*- coding:utf-8 -*- class E: #经典类 pass class E1(object): #新式类 pass e = E() print ("经典类") print (e) print (type(e)) print (e.__class__) e1 = E1() print ("新式类") print (e1) print (type(e1)) print (e1.__class__) 输出: 经典类 <__main__.E object at 0x102978748> <class '__main__.E'> <class '__main__.E'> 新式类 <__main__.E1 object at 0x102978828> <class '__main__.E1'> <class '__main__.E1'> ==================================== """python 2 中执行""" # -*- coding:utf-8 -*- class E: #经典类 pass class E1(object): #新式类 pass e = E() print ("经典类") print (e) print (type(e)) print (e.__class__) e1 = E1() print ("新式类") print (e1) print (type(e1)) print (e1.__class__) 输出: 经典类 <__main__.E instance at 0x10b431cb0> <type 'instance'> __main__.E 新式类 <__main__.E1 object at 0x10b420250> <class '__main__.E1'> <class '__main__.E1'> 结论:新式类对象能够直接经过__class__属性获取自身类型:type ;在python 3 中经典类与新式类是一致的。python2 的输出中,区别比较大
B、新式类与经典类的继承搜索的顺序区别
举例说明:
(1)、经典类与新式类在python3中的执行顺序是:新式类与经典类都是 D->B、C->A(先水平搜索,而后再向上移动)
举例以下:
1 """ python3中执行""" 2 """新式类""" 3 class A(object): 4 def __init__(self): 5 self.n = "A" 6 7 class B(A): 8 pass 9 10 class C(A): 11 def __init__(self): 12 self.n = "C" 13 14 class D(B,C): 15 pass 16 17 d = D() 18 print(d.n) 19 20 """经典类""" 21 class A1: 22 def __init__(self): 23 self.n = "A1" 24 25 class B1(A1): 26 pass 27 28 class C1(A1): 29 def __init__(self): 30 self.n = "C1" 31 32 class D1(B1,C1): 33 pass 34 35 d1 = D1() 36 print(d1.n) 37 38 输出: 39 C 40 C1
(2)、经典类与新式类在python2中的执行顺序是:新式类是 D->B、C->A (先水平搜索,而后再向上移动);经典类是 D->B->A-C 或者是 D->C->B->A (先深刻继承树左侧,再返回,开始找右侧。当把右侧的class C pass掉以后,继承的顺序有变动为D->C->B->A;
举例以下:
1 """新式类""" 2 class A(object): 3 def __init__(self): 4 self.n = "A" 5 6 class B(A): 7 pass 8 9 class C(A): 10 def __init__(self): 11 self.n = "C" 12 13 class D(B,C): 14 pass 15 16 d = D() 17 print d.n 18 19 20 """经典类""" 21 class A1: 22 def __init__(self): 23 self.n = "A1" 24 class B1(A1): 25 pass 26 class C1(A1): 27 def __init__(self): 28 self.n = "C1" 29 30 class D1(B1,C1): 31 pass 32 33 d1 = D1() 34 print d1.n 35 36 输出: 37 C 38 A1
三、类的多态实例
多态性(polymorphisn)是容许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值以后,父对象就能够根据当前赋值给它的子对象的特性以不一样的方式运做。简单的说,就是一句话:容许将子类类型的指针赋值给父类类型的指针。
多态的做用是什么呢?封装能够隐藏实现细节,使得代码模块化;继承能够扩展已存在的代码模块(类);它们的目的都是为了——代码重用。而多态则是为了实现另外一个目的——接口重用!多态的做用,就是为了类在继承和派生的时候,保证使用“家谱”中任一类的实例的某一属性时的正确调用。
举例:
1 # _*_coding:utf-8_*_ 2 3 class Animal(object): 4 def __init__(self, name): # Constructor of the class 5 self.name = name 6 7 def talk(self): # Abstract method, defined by convention only 8 raise NotImplementedError("Subclass must implement abstract method") 9 10 11 class Cat(Animal): 12 def talk(self): 13 print('%s: 喵喵喵!' % self.name) 14 15 16 class Dog(Animal): 17 def talk(self): 18 print('%s: 汪!汪!汪!' % self.name) 19 20 21 def func(obj): # 一个接口,多种形态 22 obj.talk() 23 24 25 c1 = Cat('小晴') 26 d1 = Dog('李磊') 27 28 func(c1) 29 func(d1) 30 输出 31 小晴: 喵喵喵! 32 小磊: 汪!汪!汪!
角色:学校、学员、课程、讲师
要求:
1. 建立北京、上海 2 所学校
2. 建立linux , python , go 3个课程 , linux\py 在北京开, go 在上海开
3. 课程包含,周期,价格,经过学校建立课程
4. 经过学校建立班级, 班级关联课程、讲师
5. 建立学员时,选择学校,关联班级
5. 建立讲师角色时要关联学校,
6. 提供两个角色接口
6.1 学员视图, 能够注册, 交学费, 选择班级,
6.2 讲师视图, 讲师可管理本身的班级, 上课时选择班级, 查看班级学员列表 , 修改所管理的学员的成绩
6.3 管理视图,建立讲师, 建立班级,建立课程
7. 上面的操做产生的数据都经过pickle序列化保存到文件里