1.面对对象不是所有情形都适用
1.1函数式编程
def fun1(arg1): pass def fun2(arg1,arg2): pass fun1("acker") fun2("...")
2.1面对对象编程
class humanBeing: def fun1(self, arg1): pass def fun2(self,arg1, arg2): pass obj1 = humanBeing() obj1.fun1(‘wuwen‘) obj2.fun2(‘henshuai‘)
结论:单从代码的复杂程度来看,面对对象编程并不是适合所有情况
2.面对对象编程的格式规范:
a.定义类
class 类名: def 方法1(self,arg) pass
b.根据类创建对象(创建一个**类的实例)
使用对象去执行类中的方法(函数编程中,我们称之为函数),如下图为类与对象的关系
3.类的方法的默认参数self
self,形式参数,代指执行方法的对象,在python内部传递,为封装而生
class humanBeing: def fun1(self, name): print(self, name) def fun2(self, name, gender): print(self, name, gender) obj1 = humanBeing() print(obj1) obj1.fun1(‘acker‘) obj1.fun2(‘acker‘, ‘female‘) #<__main__.humanBeing object at 0x02171210> #<__main__.humanBeing object at 0x02171210> wuwen #<__main__.humanBeing object at 0x02131490> wuwen female #总结:self为实例本身的内存地址
4.封装:
当每个函数里面都需要用到相同的参数(如上类方法中的name参数),我们可以提前把参数封装到对象(实例)中去
class humanBeing: def fun1(self): print(self.name) def fun2(self, gender): print(self.name, gender) obj1 = humanBeing() obj1.name = ‘acker‘ obj1.fun1() #acker
5.用初始化封装
类名+() ---->>> 自动执行类中的__init__方法;创建一个对象
在__init__方法中执行具体封装的操作
__init__有一个特殊名字:构造方法
__del__有一个特殊的名字:析构器
class Oldboy: def __init__(self, backend, record): ‘‘‘ 构造方法 :param backend: :param record: ‘‘‘ # 普通字段 self.backend = backend self.record = record def fetch(self): print(self.backend) def add_record(self): print(self.record) def del_record(self): print(self.record) # 创建对象,并且封装 obj1 = Oldboy(‘www.oldboy.org‘, ‘wohenshuai‘) # 执行方法,执行过程中可以根据self去obj1中去取已经封装在里面的数据 obj1.fetch() obj1.add_record() obj1.del_record()
5.1 小游戏(可以用pickle存档)
pickle可以将一个类的对象序列化
class person: def __init__(self, name, age, weight): self.Name = name self.Age = age self.Weight = weight def chi(self): self.Weight = self.Weight + 2 print("%s 吃" % self.Name) def bodybuilding(self): self.Weight = self.Weight - 1 import pickle # pickle 可以序列化对象,json只能处理字符串,数字,字典,列表与元组 # 游戏存档 ret = pickle.load(open(‘cundang.log‘, ‘rb‘)) print(ret) if ret: print(ret.Weight) else: o1 = person(‘小明‘, 5, 200) o1.bodybuilding() o1.chi() o1.chi() o1.chi() o1.chi() o1.chi() o1.chi() pickle.dump(o1, open(‘cundang.log‘, ‘wb‘)) # 将对象存档
6.继承
6.1 单继承
‘‘‘ 子类继承父类所有的功能 父类不能使用子类的功能 当父类和子类同时具有某种功能时: 对于由父类创建的对象,则使用自己的功能,因为它无法继承自己的子类。 对于子类创建的的对象,我们也使用自己的功能,因为,优先级的先后。 ‘‘‘ class Animals: def chi(self): print(self.name + ‘吃‘) def he(self): print(self.name + ‘喝‘) def piao(self): print(‘爱piao‘) class Dog(Animals): def __init__(self, name): self.name = name def wang(self): print(self.name + ‘汪汪汪~‘) def piao(self): print(‘不爱piao‘) obj1 = Dog(‘桃桃‘) obj1.piao() ‘‘‘ 不爱piao ‘‘‘
6.2 多继承(笔试易考)
#!/usr/bin env python # -*- coding:utf-8 -*- ‘‘‘ 在c++和java中,一个子类只能继承一个父类 但是在python中,一个子类可以继承多个父类 ‘‘‘ class Animals: def chi(self): print(self.name + ‘吃‘) def he(self): print(self.name + ‘喝‘) def piao(self): print(‘爱piao‘) class Uncle: def du(self): print(‘赌‘) def piao(self): print(‘很爱piao‘) class Dog(Animals, Uncle): ‘‘‘ 先继承Animals和Uncle父类中不重复的方法 对不重复的方法:优先找自己,其次第一个父类Animals,最后第二个父类Uncle ‘‘‘ def __init__(self, name): self.name = name def wang(self): print(self.name + ‘汪汪汪~‘) def piao(self): print(‘不爱piao‘) obj1 = Dog(‘taotao‘) obj1.piao() ‘‘‘ 不爱piao ‘‘‘
6.3 继承顺序
6.3.1 无共同父类
class A: def f(self): print(‘A‘) class B: def f1(self): print(‘B‘) class C(A): def f(self): print(‘C‘) class D(B): def f1(self): print(‘D‘) class E(C, D): def f(self): print(‘E‘) obj1 = E() obj1.f1() ‘‘‘ D ‘‘‘
6.3.2 有共同父类
class Top: def f1(self): print(‘Top‘) class A(Top): def f(self): print(‘A‘) class B(Top): def f1(self): print(‘B‘) class C(A): def f(self): print(‘C‘) class D(B): def f1(self): print(‘D‘) class E(C, D): def f(self): print(‘E‘) obj1 = E() obj1.f1() ‘‘‘ D ‘‘‘
7.多态
Pyhon不支持Java和C#这一类强类型语言中多态的写法,但是原生多态,其Python崇尚“鸭子类型”
1 1 class F1: 2 2 pass 3 3 4 4 5 5 class S1(F1): 6 6 7 7 def show(self): 8 8 print ‘S1.show‘ 9 9 10 10 11 11 class S2(F1): 12 12 13 13 def show(self): 14 14 print ‘S2.show‘ 15 15 16 16 17 17 # 由于在Java或C#中定义函数参数时,必须指定参数的类型 18 18 # 为了让Func函数既可以执行S1对象的show方法,又可以执行S2对象的show方法,所以,定义了一个S1和S2类的父类 19 19 # 而实际传入的参数是:S1对象和S2对象 20 20 21 21 def Func(F1 obj): 22 22 """Func函数需要接收一个F1类型或者F1子类的类型""" 23 23 24 24 print obj.show() 25 25 26 26 s1_obj = S1() 27 27 Func(s1_obj) # 在Func函数中传入S1类的对象 s1_obj,执行 S1 的show方法,结果:S1.show 28 28 29 29 s2_obj = S2() 30 30 Func(s2_obj) # 在Func函数中传入Ss类的对象 ss_obj,执行 Ss 的show方法,结果:S2.show
Python伪代码实现Java或C#的多态
1 1 class F1: 2 2 pass 3 3 4 4 5 5 class S1(F1): 6 6 7 7 def show(self): 8 8 print ‘S1.show‘ 9 9 10 10 11 11 class S2(F1): 12 12 13 13 def show(self): 14 14 print ‘S2.show‘ 15 15 16 16 def Func(obj): 17 17 print obj.show() 18 18 19 19 s1_obj = S1() 20 20 Func(s1_obj) 21 21 22 22 s2_obj = S2() 23 23 Func(s2_obj)
Python “鸭子类型”
8.经典问答
问题一:什么样的代码才是面向对象?
答:从简单来说,如果程序中的所有功能都是用 类 和 对象 来实现,那么就是面向对象编程了。
问题二:函数式编程 和 面向对象 如何选择?分别在什么情况下使用?
答:须知:对于 C# 和 Java 程序员来说不存在这个问题,因为该两门语言只支持面向对象编程(不支持函数式编程)。
而对于 Python 和 PHP 等语言却同时支持两种编程方式,且函数式编程能完成的操作,面向对象都可以实现;而面
向对象的能完成的操作,函数式编程不行(函数式编程无法实现面向对象的封装功能)。
所以,一般在Python开发中,全部使用面向对象 或 面向对象和函数式混合使用
9.面对对象的应用场景
9.1 多函数需使用共同的值,如:数据库的增、删、改、查操作都需要连接数据库字符串、主机名、用户名和密码
class SqlHelper: def __init__(self, host, user, pwd): self.host = host self.user = user self.pwd = pwd def 增(self): # 使用主机名、用户名、密码(self.host 、self.user 、self.pwd)打开数据库连接 # do something # 关闭数据库连接 def 删(self): # 使用主机名、用户名、密码(self.host 、self.user 、self.pwd)打开数据库连接 # do something # 关闭数据库连接 def 改(self): # 使用主机名、用户名、密码(self.host 、self.user 、self.pwd)打开数据库连接 # do something # 关闭数据库连接 def 查(self): # 使用主机名、用户名、密码(self.host 、self.user 、self.pwd)打开数据库连接 # do something # 关闭数据库连接# do something
9.2 需要创建多个事物,每个事物属性个数相同,但是值的需求
如:张三、李四、杨五,他们都有姓名、年龄、血型,但其都是不相同。即:属性个数相同,但值不相同
class Person: def __init__(self, name ,age ,blood_type): self.name = name self.age = age self.blood_type = blood_type def detail(self): temp = "i am %s, age %s , blood type %s " % (self.name, self.age, self.blood_type) print temp zhangsan = Person(‘张三‘, 18, ‘A‘) lisi = Person(‘李四‘, 73, ‘AB‘) yangwu = Person(‘杨五‘, 84, ‘A‘)