面向对象之封装
一、面向对象的精髓
精髓就是将数据和处理数据的代码绑定成了一个对象,只要获取到对象,相应的数据和方法都有了。
1 #1、在没有学习类这个概念时,数据与功能是分离的 2 def exc1(host,port,db,charset,sql): 3 conn=connect(host,port,db,charset) 4 conn.execute(sql) 5 return 123 6 7 8 def exc2(host,port,db,charset,proc_name): 9 conn=connect(host,port,db,charset) 10 conn.call_proc(proc_name) 11 return 123 12 13 14 def exc2(host,port,db,charset,proc_name): 15 conn=connect(host,port,db,charset) 16 conn.call_proc(proc_name) 17 return 123 18 #每次调用都需要重复传入一堆参数 19 exc1('127.0.0.1',3306,'db1','utf8','select * from tb1;') 20 21 exc2('127.0.0.1',3306,'db1','utf8','存储过程的名字') 22 23 #2、使用面向对象
24 class Mysql: 25 26 def __init__(self,host,port,db,charset): 27 self.host = host 28 self.port = port 29 self.db = db 30 self.charset = charset 31 32 def exc2(self,proc_name): 33 conn=connect(self.host,self.port,self.db,self.charset) 34 conn.call_proc(proc_name) 35 return 123 36 37 def exc1(self,sql): 38 conn=connect(self.host,self.port,self.db,self.charset) 39 conn.execute(sql) 40 return 123 41 42 43 my1 = Mysql("127.0.0.1",3306,"mydb","utf-8") 44 45 my1.exc1("select *from table1") 46 my1.exc2("名字")
二、组合
1.什么是组合?
组合指的是某一个对象拥有一个属性,该属性的值是另外一个类的对象。
2.为何要用组合?
通过为某一个对象添加属性,属性的值是另外一个类的对象的方式,可以间接地将两个类关联/整合/组合到一起,从而减少类与类之间的代码冗余。
3.如何用组合?
#学生老师系统中添加一个课程,学生可以查看他选修的课程,老师也可以查看他任课的课程 class OldboyPeople(object): def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex class OldboyStudent(OldboyPeople): def __init__(self,name,age,sex,score=0): super().__init__(name,age,sex) self.score=score self.courses=[] def chose_courses(self): print("%s chose courses"%self.name) def show_courses(self): print("%s学生选修的课程:"%self.name) for i in self.courses: i.tell_info() class OldschoolTeacher(OldboyPeople): def __init__(self,name,age,sex,level): super(OldschoolTeacher, self).__init__(name,age,sex) self.level=level self.courses=[] def score(self): pass def show_courses(self): print("%s老师开课的课程:"%self.name) for i in self.courses: i.tell_info() class Course(object): def __init__(self,c_name,c_price,c_period): self.c_name=c_name self.c_price=c_price self.c_period=c_period def tell_info(self): print("<课程:%s 价格:%s 周期:%s>"%(self.c_name,self.c_price,self.c_period)) python=Course("python全栈开发",17800,"6个月") linux=Course("linux",16800,"5个月") stu1=OldboyStudent("周冬",18,"男") stu2=OldboyStudent("赖正荣",28,"男") tea1=OldschoolTeacher("林海峰",18,"男",10) stu1.courses.append(python) stu1.courses.append(linux) tea1.courses.append(linux) stu1.show_courses() tea1.show_courses()
三、封装
1.什么是封装?
封:将存放于名称空间中的名字给藏起来,这种隐藏对外不对内。
装:往容器/名称空间中存名字
在程序中封装指的是对外隐藏内部的实现细节,并对外部提供使用接口,从而严格控制对类中的属性的操作。
2.为何要用封装?
2.1可以提高安全性,不对外开放类内部的实现细节,同时也可以在封装时,在外部提供的接口中增加额外的逻辑判断,依次来提高安全性。
2.2封装同时也是为了明确区分类的内部和外部。
2.3封装函数的属性可以隔离复杂度。
# ATM 的取款功能 # 1.插入银行卡 2.输入密码 3.选择取款金额 4.取款 class ATM: def __insert_card(self): print("插入银行卡...") def __input_pwd(self): print("输入密码...") def __select_money(self): print("选择取款金额...") def withdraw(self): self.__insert_card() self.__input_pwd() self.__select_money() print("取款成功!....") atm = ATM() atm.withdraw() # 外部调用这个简单的接口 就能完成一系列复杂的操作
3.如何使用封装?
在属性或者方法名称前,加上两个下划线,就可以将其设置为私有的。
class Student: def __init__(self,name,age,sex,id_card): self.name=name self.age=age self.sex=sex self.__id_card=id_card def show_id_card(self): print(self.__id_card) stu1=Student("钟大俊",20,"男","330133013302") #print(stu1.id_card) 是访问不到的,因为已经进行了封装 #print(__stu1.id_card) 为什么用__开头也找不到呢?接下去看 #此时我们查看stu1中的所有属性,利用__dict__查看 print(stu1.__dict__) #>>>:{'name': '钟大俊', 'age': 20, 'sex': '男', '_Student__id_card': '330133013302'} #发现__stu1.id_card变成了_Student__id_card,原来封装的时候原来的属性名称发生了变形,且这个变形只在类的定义阶段才会发生。 #也就是说: stu1.__score=90 print(stu1.__score) #此时能访问到的,属性名不在定义阶段加上__时不会发生变形。 #>>>:90
总结:
1. __开头的属性实现的隐藏仅仅只是一种语法意义上的变形,并不会真的限制类外部的访问
2. 该变形操作只在类定义阶段检测语法时发生一次,类定义阶段之后新增的__开头的属性并不会变形。
3. 如果父类不想让子类覆盖自己的属性,可以在属性前加__开头
杜绝秃头!!!