面向过程的程序设计
核心是过程二字,指解决问题的步骤,即先干什么再干什么...好比一条流水线,一种比较机械化的思维方式
优点:问题流程化,复杂的问题拆分成一个一个步骤组合而解决,进而解决复杂的问题,变简单化
缺点:一套流程只能用来解决一个问题,即便是能解决其他问题,也得改动,改一处,牵一发而动全身
应用场景:一旦完成,基本很少改变的场景,如linux内核,git,以及Apache HTTP Server等
面向对象的程序设计
核心是对象二字,何为对象?站在上帝的角度来考虑万物,一切皆对象,每个对象都有他各自的特征和功能,面向对象程序设计好比在创造一个世界,你就是这个世界的造物者,存在的皆为对象,不存在的也可以创造出来,与面向过程机械化的思维形成鲜明对比,面向更注重对现实世界的模拟,是一种"上帝式"的思维方式
优点:解决了程序的扩展性,单独修改一个对象,会立刻反应到整个体系中,如对游戏中一个人物的参数修改,会立马反应到游戏当中
缺点:复杂度高于面向过程,极容易出现过度设计的问题,一些扩展性要求低的场景使用面向对象会徒增编程难度,如管理linux系统的shell脚本就不适合用面向对象去设计,面向过程反而更加适合
无法面向过程的程序设计流水线式的可以很精准的预测问题的处理流程与记过,而面向对象的程序一旦开始,就是对象之间相互交互解决问题了,即便是上帝也无法准确预测最终结果
应用场景:需求经常变化的软件,多集中在用户层,互联网应用,企业内部软件,游戏等,这些都是面向对象的程序设计大显身手的好地方
面向对象的程序设计并不是全部。对于一个软件质量来说,面向对象的程序设计只是用来解决扩展性。
类与对象
类从现实认知来讲,即种类,类别,比如,人类,植物类,动物类
对象就是某一类中的一个个体,有自己的特征和功能,如人类中的人,植物类中的梧桐树,动物类中的老虎
在现实世界中:先有对象,再有类
世界上肯定是先出现各种各样的实际存在的物体,然后随着人类文明的发展,人类站在不同的角度总结出了不同的种类,如人类、动物类、植物类等概念
也就说,对象是具体的存在,而类仅仅只是一个概念,并不真实存在
在程序中:与现实恰恰相反,务必保证先定义类,后产生对象
与函数有些类似,先定义函数,后调用函数,类也是一样,在程序中需要先定义类,后调用类,与函数不同的事,调用函数会执行函数中的代码返回的也是代码执行的结果,而调用类会产生对象,返回的是对象
#面向对象方式格式:class 类名: #- 定义了一个类 def 函数名(self): #- 在类中编写了一个"方法" pass 调用:x1 = 类名() #- 创建了一个对象/实例化一个对象x1.函数名() #- 通过对象调用其中一个方法. # 示例class Account: def login(self): # self是必须要写的 user = input('请输入用户名:') pwd = input('请输入密码:') if user == 'zkx' and pwd == 'shuaibi': print('登录成功') else: print('登录失败')obj = Account() # 调用类obj.login() #执行类中的方法# 运行结果"""请输入用户名:zkx请输入密码:shuaibi登陆成功"""
类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称, 按照惯例它的名称是 self。
构造方法__init__
实例化:类名加括号就是实例化,会自动触发__init__函数的运行,可以用它来为每个实例定制自己的特征
self代表类的实例,而非类
示例:
""" 示例 """class Foo: def __init__(self,name): #构造方法,目的进行数据初始化. self.name = name self.age = 18 obj = Foo('jay')#通过构造方法,可以将数据进行打包,以后使用时,去其中获取即可. print(obj.name)print(obj.age)"""运行结果jay18"""
应用
a.将数据封装到对象中, 以供自己在方法中调用class FileHandler: def __init__(self, file_path): self.file_path = file_path self.f = open(self.file_path, 'rb') def read_first(self): # self.f.read() # ... pass def read_last(self): # self.f.read() # ... pass def read_second(self): # self.f... # ... passobj = FileHandler('C:/xx/xx.log')obj.read_first()obj.read_last()obj.read_second()obj.f.close()b.将数据封装到对象中, 以供其他函数调用def new_func(arg): arg.k1 arg.k2 arg.k6class Foo: def __init__(self, k1, k2, k6): self.k1 = k1 self.k2 = k2 self.k6 = k6obj = Foo(111, 22, 333)new_func(obj)
1 """ 2 信息管理系统 3 1. 用户登录 4 2. 显示当前用户信息 5 3. 查看当前用户所有的账单 6 4. 购买姑娘形状的抱枕 7 """ 8 class UserInfo: 9 10 def __init__(self):11 self.name = None12 13 def info(self):14 print('当前用户名称:%s' % (self.name,))15 16 def account(self):17 print('当前用户%s的账单是:....' % (self.name,))18 19 def shopping(self):20 print('%s购买了一个人形抱枕' % (self.name,))21 22 def login(self):23 user = input('请输入用户名:')24 pwd = input('请输入密码:')25 if pwd == 'sb':26 self.name = user27 while True:28 print("""29 1. 查看用户信息30 2. 查看用户账单31 3. 购买抱枕32 """)33 num = int(input('请输入选择的序号:'))34 if num == 1:35 self.info()36 elif num == 2:37 self.account()38 elif num == 3:39 self.shopping()40 else:41 print('序号不存在,请重新输入')42 else:43 print('登录失败')44 45 46 obj = UserInfo()47 obj.login()
面向对象的代码编写
规则:
class Foo: # 定义一个类 def __init__(self, name): #封装了一个方法 self.name = name def detail(self, msg): print(self.name, msg)obj = Foo() # 调用了一个类 obj.detail() #执行了类中的一个方法
什么时候用面向对象程序设计?如何写?
归类的时候,也可以讲你想用就用,如何分类?想怎么分就怎么分,跟着感觉走,慢慢会发现不足的
方法一:归类+提取公共值
归类:class File: def file_read(self, file_path): pass def file_update(self, file_path): pass def file_delete(self, file_path): pass def file_add(self, file_path): passclass Excel: def excel_read(self, file_path): pass def excel_update(self, file_path): pass def excel_delete(self, file_path): pass def excel_add(self, file_path): pass提取公共值:class File: def __init__(self, file_path): self.file_path = file_path def file_read(self): pass def file_update(self): pass def file_delete(self): pass def file_add(self): passclass Excel: def __init__(self, file_path): self.file_path = file_path def excel_read(self): pass def excel_update(self): pass def excel_delete(self): pass def excel_add(self): pass注意:这是从下往上推的,也就是逆向
方式二:在指定类中编写和当前类相关的所有代码 + 提取公共值
方式二: 在指定类中编写和当前类相关的所有代码 + 提取公共值class Message: def email(self): passclass Person: def __init__(self, na, gen, age, fig) self.name = na self.gender = gen self.age = age self.fight = fig def grassland(self): self.fight = self.fight - 10 def practice(self): self.fight = self.fight + 90 def incest(self): self.fight = self.fight - 666cang = Person('瑞雯', '女', 18, 1000) # 创建瑞雯角色dong = Person('盖伦', '男', 20, 1800) # 创建盖伦角色bo = Person('卡特', '女', 19, 2500) # 创建卡特角色dong.grassland() # 正向
面向对象的三大特征:封装/继承/多态
1 封装: 2 将相关功能封装到一个类中: 3 4 5 class Message: 6 def email(self): pass 7 8 def msg(self): pass 9 10 def wechat(self): pass11 12 13 将数据封装到一个对象中:14 15 16 class Person:17 def __init__(self, name, age, gender):18 self.name = name19 self.age = age20 self.gender = gender21 22 23 obj = Person('jamrry', 18, '女')
1 继承: 2 3 4 class SuperBase: 5 def f3(self): 6 print('f3') 7 8 9 class Base(SuperBase): # 父类,又叫基类10 def f2(self):11 print('f2')12 13 14 class Foo(Base): # 子类,又叫派生类15 16 def f1(self):17 print('f1')18 19 20 obj = Foo()21 obj.f1()22 obj.f2()23 obj.f3()24 # 原则:现在自己类中找,么有就去父类25 """26 运行结果:27 f128 f229 f330 """
1 """" 2 多态: 3 多种形态或多种状态 4 鸭子模型, 只要可以嘎嘎叫就是鸭子. 5 """ 6 7 # Python 8 # 由于python原生支持多态,所以没有特殊性. 9 class Foo1:10 def f1(self):11 pass 12 13 class Foo2:14 def f1(self):15 pass 16 17 class Foo3:18 def f1(self):19 pass 20 21 22 def func(arg):23 arg.f1()24 25 obj = Foo1() # obj= Foo2() obj = Foo3()26 func(obj)27 28 29 # java30 31 32 class Son(list):33 pass34 35 36 class Son1(list):37 pass38 39 40 # 以后传参时,arg可以是:list类的对象/list任何子类的对象41 public42 void43 func(list44 arg){45 print(arg)46 }
总结:
1. 继承编写 class Foo(父类): pass 2. 支持多继承(先找左/再找右) 3. 多继承:提供代码重用性 4. 找self到底是谁的对象?从谁开始找,self就一直就是那个类的实例