什么是面向对象编程
- 类 + 对象
- class 类:
- def 函数1():
- pass
- def 函数2():
- pass
- def 函数1():
- obj是对象, 实例化的过程
- obj = 类()
- obj.函数1()
- class 类:
例1 , 某些方法被反复调用. 如: 登录服务器并上传文件.
函数式编程:
def upload(): # 连接服务器 # 上传文件 # 关闭 def cmd(): # 连接服务器 # 执行命令 # 关闭 def upload_cmd(): # 连接服务器 # 上传文件 # 执行命令 # 关闭
面向对象编程:
class SSH: def __init__(self, host, port, pwd, username): self.host= ... def connection(self): # 去创建连接 self.conn = 和服务器创建的连接对象() def close(self): # 关闭 self.conn.关闭 def upload(self): self.conn 使用连接上传文件 def cmd(self): self.conn 使用连接执行命令 obj = SSH(.......) obj.connection() obj.upload() obj.close() obj = SSH(.......) obj.connection() obj.cmd() obj.cmd() obj.upload() obj.cmd() obj.close()
注: 若需要改变服务器连接, 函数式编程所有函数都需要修改; 而面向对象编程只需要更改connection()方法即可.
例2: 多个函数需要传入多个共同的参数. 如:多个函数需要的参数有相同部分也有不同部分(类似java中方法重载)
函数式编程:
def f1(host, port, pwd, arg) pass def f2(host, port, pwd, arg, arg2) pass def f3(host, port, pwd, arg, arg2, arg3) pass f1(1,1,1,2) f2(1,1,1,2,2) f3(1,1,1,2,2,3)
面向对象编程:
class Foo: def __init__(self, host, port, pwd): self.host = host self.port = port self.pwd = pwd def f1(arg): pass def f2(arg,arg2): pass def f3(arg, arg2, arg3): pass obj = Foo(1,1,1) obj.f1(1) obj.f2(2,2) obj.f3(3,3,3)
什么时候适用面向对象
- 多个步骤在不同函数中反复调用.可以将各个步骤抽取出来写在一个类中,每个步骤写一个方法,这样调用时就可以任意组合.
- 根据一个模版创建某些东西(也是加以某些限制)
- 多个函数传入多个共同的参数时,可以写在一个类中,共同的参数抽取出来写在构造函数中.
class Foo: # 静态字段 (公有属性), 适合每一个对象都有的共同的值时, 把这个值抽取出来作为静态字段. country = "中国" def __init__(self, name, count): # 普通字段(普通属性) self.name = name self.count = count def bar(self): pass obj1 = Foo('河南', 100000) obj1.bar()
封装:
- 类中封装: 字段, 方法
- 对象中封装: 普通字段的值
-
class F1: def __init__(self, n): self.n = n print('F1') class F2: def __init__(self, arg1): self.a = arg1 print('F2') class F3: def __init__(self, arg2): self.b = arg2 print('F3') o1 = F1('alex') o2 = F2(o1) o3 = F3(o2) print(o3.b.a.n) # 输出alex
继承:
- self代指当前对象
-
class F1: def __init__(self): print('F1') def a1(self): print('F1a1') def a2(self): print('F1a2') class F2(F1): def __init__(self): print('F2') def a1(self): self.a2() print('F2a1') def a2(self): print('F2a2') class F3(F2): def __init__(self): print('F3') # def a1(self): # print('F3a1') def a2(self): print('F3a2') obj = F3() obj.a1() # 先返回F3a2然后返回F2a1
字段
- 普通字段(保存在对象中)
- 静态字段(保存在类中)
方法
- 普通方法(保存在类中, 调用者对象)
- 静态方法(可以有任意个参数)
- 在方法上添加注释 @staticmethod
- 不需要创建对象,可以直接类名.方法()调用
-
class F1: @staticmethod # 标识某方法为静态方法 def a1(): print('alex') F1.a1() # 调用方法
组合
- 把一个类实例化, 实例化对象作为参数传入另一个类.
-
#!/usr/bin/python # -*- coding: utf-8 -*- """ 命名规范: 1. 类名每个单词都要首字母大写 2. 类名下面要写注释 """ 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): """ 注册 :return: """ print("just enrolled a new school memeber [%s]" % self.name) # self.member += 1 # 每新注册一个, 成员数加1. 这样写只是当前子类成员数加1;要想父类SchoolMember总成员数加1, 需得加到全局变量里. SchoolMember.member += 1 def tell(self): print('------------%s info ----------' % self.name) for k, v in self.__dict__.items(): # __dict__方法可以打印出类的所有变量 print(" ", k, v) print("end".center(33, "-")) def __del__(self): print("开除了[%s]" % self.name) SchoolMember.member -= 1 class School(object): """ 假装是另一个社团团员类(以便Teacher和Student能继承;否则School是个组织, Teacher/Student是不能继承的) """ def open_branch(self, addr): print("opening new branch in ", addr) class Student(SchoolMember): def __init__(self,name, age, sex, course, tuition, school_obj): SchoolMember.__init__(self, name, age, sex) self.school = school_obj # 组合. 相当于把School实例化, 再把实例化对象传入Student作为一个参数,这样就可以调用School的变量和方法 self.course = course self.tuition = tuition # fee # self.enroll() # enroll()方法在每个子类里都需要, 可以直接写在父类里 self.amount = 0 def pay_tuition(self, amount): print("student [%s] has just paid [%s]" %(self.name, amount)) self.amount += amount