面向对象的程序设计
什么是面向对象的程序设计及为什么要有它
面向过程的程序设计:核心是过程二字,过程指的是解决问题的步骤,即先干什么再干什么......面向过程的设计就好比精心设计好一条流水线,是一种机械式的思维方式。
优点是:复杂度的问题流程化,进而简单化(一个复杂的问题,分成一个个小的步骤去实现,实现小的步骤将会非常简单)
缺点是:一套流水线或者流程就是用来解决一个问题,生产汽水的流水线无法生产汽车,即便是能,也得是大改,改一个组件,牵一发而动全身。
应用场景:一旦完成基本很少改变的场景,著名的例子有Linux內核,git,以及Apache HTTP Server等。
面向对象的程序设计:核心是对象二字,(要理解对象为何物,必须把自己当成上帝,上帝眼里世间存在的万物皆为对象,不存在的也可以创造出来。面向对象的程序设计好比如来设计西游记,如来要解决的问题是把经书传给东土大唐,如来想了想解决这个问题需要四个人:唐僧,沙和尚,猪八戒,孙悟空,每个人都有各自的特征和技能(这就是对象的概念,特征和技能分别对应对象的数据属性和方法属性),然而这并不好玩,于是如来又安排了一群妖魔鬼怪,为了防止师徒四人在取经路上被搞死,又安排了一群神仙保驾护航,这些都是对象。然后取经开始,师徒四人与妖魔鬼怪神仙交互着直到最后取得真经。如来根本不会管师徒四人按照什么流程去取),对象是特征与技能的结合体,基于面向对象设计程序就好比在创造一个世界,你就是这个世界的上帝,存在的皆为对象,不存在的也可以创造出来,与面向过程机械式的思维方式形成鲜明对比,面向对象更加注重对现实世界的模拟,是一种“上帝式”的思维方式。
优点是:解决了程序的扩展性。对某一个对象单独修改,会立刻反映到整个体系中,如对游戏中一个人物参数的特征和技能修改都很容易。
缺点:
1. 编程的复杂度远高于面向过程,不了解面向对象而立即上手基于它设计程序,极容易出现过度设计的问题。一些扩展性要求低的场景使用面向对象会徒增编程难度,比如管理linux系统的shell脚本就不适合用面向对象去设计,面向过程反而更加适合。
2. 无法向面向过程的程序设计流水线式的可以很精准的预测问题的处理流程与结果,面向对象的程序一旦开始就由对象之间的交互解决问题,即便是上帝也无法准确地预测最终结果。于是我们经常看到对战类游戏,新增一个游戏人物,在对战的过程中极容易出现阴霸的技能,一刀砍死3个人,这种情况是无法准确预知的,只有对象之间交互才能准确地知道最终的结果。
应用场景:需求经常变化的软件,一般需求的变化都集中在用户层,互联网应用,企业内部软件,游戏等都是面向对象的程序设计大显身手的好地方
面向对象的程序设计并不是全部。对于一个软件质量来说,面向对象的程序设计只是用来解决扩展性。

1、类与对象
Class 类
一个类即是对一类拥有相同属性的对象的抽象、蓝图、原型。在类中定义了这些对象的都具备的属性(variables(data))、共同的方法
Object 对象
一个对象即是一个类的实例化后实例,一个类必须经过实例化后方可在程序中调用,一个类可以实例化多个对象,每个对象亦可以有不同的属性,就像人类是指所有人,每个人是指具体的对象,人与人之前有共性,亦有不同
2、面向对象编程举例
1 class player: 2 n =123 #类变量 3 name = "这里是类名字" 4 def __init__(self , name ,job, gun , life = 100 , money = 10000): #构造函数 在实例化时做一些类的初始化的工作 5 self.name = name #r1.name=name实例变量(静态属性),作用域就是实例本身 6 self.job = job 7 self.gun = gun 8 self.__life = life #私有变量 外面不可以访问,里面可以改 9 self.money = money 10 11 def __del__(self):#析构函数:在实例释放、销毁的时候自动执行的,通常用于做一些收尾工作,如关闭一些数据库连接,关闭打开的临时文件 12 print("%s退出游戏"%self.name) 13 14 def __kill(self): 15 print("%s击败一人"%self.name) 16 17 def injured(self): #类的方法,功能(动态属性) 18 self.__life = self.__life - 50 19 print("%s受到10点伤害,生命值-50,当前生命值为%s"%(self.name,self.__life)) 20 # if self.life <= 0 : 21 # del self 22 23 def buy_gun(self,gun): 24 self.gun = gun 25 self.money = self.money -1000 26 print("%s花费1000买了%s,当前金钱为%s"%(self.name,self.gun,self.money)) 27 28 r1=player("大哥","警察","M4a1") 29 r2=player("小弟","土匪","AK47") 30 r3=player("路人","土匪","UMP9") 31 32 r3.injured() 33 r2.buy_gun("沙漠之鹰") 34 r3.injured() 35 r3.injured() 36 # 大哥受到10点伤害,生命值-10,当前生命值为90 37 # 小弟花费1000买了沙漠之鹰,当前金钱为9000 38 # 大哥受到10点伤害,生命值-10,当前生命值为80 39 # print(r1.__life) #在外部访问不了私有变量生命值 40 # r1.__kill #在外部访问不了私有方法 41 42 43 #类变量和实例变量 44 print(player.name,r1.name) #这里是类名字 大哥 45 print(player.n , r1.n) #123 123 46 47 r1.n = "改变123" #在r1里自身创建一个 n 48 print("r1:%s,r2:%s"%(r1.n,r2.n)) #r1:改变123,r2:123 49 player.n = "456" 50 print("r1:%s,r2:%s"%(r1.n,r2.n)) #r1:改变123,r2:456 51 52 53 #删除实例变量 54 print(r1.gun) 55 del r1.gun 56 # print(r1.gun)
3、面向对象的特性
封装
封装最好理解了。封装是面向对象的特征之一,是对象和类概念的主要特性。
封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。
继承
面向对象编程 (OOP) 语言的一个主要功能就是“继承”。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。
通过继承创建的新类称为“子类”或“派生类”。
被继承的类称为“基类”、“父类”或“超类”。
继承的过程,就是从一般到特殊的过程。
要实现继承,可以通过“继承”(Inheritance)和“组合”(Composition)来实现。
在某些 OOP 语言中,一个子类可以继承多个基类。但是一般情况下,一个子类只能有一个基类,要实现多重继承,可以通过多级继承来实现。
继承概念的实现方式主要有2类:实现继承、接口继承。
Ø 接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力(子类重构爹类方法);
抽象类仅定义将由子类创建的一般属性和方法。
OO开发范式大致为:划分对象→抽象类→将类组织成为层次化结构(继承和合成) →用类与实例进行设计和实现几个阶段。
1 # class Person: #经典类 2 class Person(object): #新式类 3 def __init__(self,name,age): 4 self.name = name 5 self.age = age 6 7 def sleep(self): 8 print("%s在睡觉"%self.name) 9 10 def eat(self): 11 print("%s在吃饭" % self.name) 12 13 def work(self): 14 print("%s在工作" % self.name) 15 16 class relation(object): 17 def makefriend(self,obj): 18 print("%s和%s交朋友了"%(self.name,obj.name)) 19 20 class Man(Person,relation): #类的继承 多继承 21 def __init__(self,name,age,power): #重构初始化 22 23 # Person.__init__(self,name,age) #第一种 24 25 # self.name =name #第二种 26 # self.age = age 27 super(Man, self).__init__(name,age) #第三种 更方便 28 self.power = power 29 30 def sleep(self): #方法的重构 31 Person.sleep(self) 32 print("%s在打呼噜" % self.name) 33 34 class WoMan(Person,relation): 35 def sport(self): 36 print("%s在运动" % self.name) 37 38 39 40 p1 = Person("大哥","22") 41 m1 = Man("大哥","18","100kg") 42 w1 = WoMan("大姐","20") 43 44 m1.eat() 45 m1.sleep() 46 w1.sport() 47 m1.makefriend(w1)
1 __author__ = "Alex Li" 2 # 继承顺序的区别 3 # 主要是在多重继承时才会遇到这个问题。 4 # 经典类的钻石继承是深度优先,即从下往上搜索;新式类的继承顺序是采用C3算法(非广度优先)。 5 # py2 经典类是按深度优先来继承的,新式类是按广度优先来继承的 6 # py3 经典类和新式类都是统一按广度优先来继承的 7 class A: 8 def __init__(self): 9 print("A") 10 class B(A): 11 pass 12 # def __init__(self): 13 # print("B") 14 class C(A): 15 pass 16 # def __init__(self): 17 # print("C") 18 class D(B,C): 19 pass 20 # def __init__(self): 21 # print("D") 22 23 24 obj = D()
注意:
py2 经典类是按深度优先来继承的,新式类是按广度优先来继承的
py3 经典类和新式类都是统一按广度优先来继承的
多态
多态性(polymorphisn)是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。
那么,多态的作用是什么呢?我们知道,封装可以隐藏实现细节,使得代码模块化;继承可以扩展已存在的代码模块(类);它们的目的都是为了——代码重用。而多态则是为了实现另一个目的——接口重用!多态的作用,就是为了类在继承和派生的时候,保证使用“家谱”中任一类的实例的某一属性时的正确调用。
Pyhon 很多语法都是支持多态的,比如 len(),sorted(), 你给len传字符串就返回字符串的长度,传列表就返回列表长度。
1 #多态 一种接口,多种实现 2 class Animal(object): 3 def __init__(self,name): 4 self.name = name 5 6 def talk(self): 7 pass 8 9 @staticmethod #实现多态 10 def animal_talk(obj): 11 obj.talk() 12 13 14 class dog(Animal): 15 def talk(self): 16 print("汪汪汪") 17 18 class cat(Animal): 19 def talk(self): 20 print("喵喵喵") 21 22 a1 = dog("小狗") 23 a2 = cat("小猫") 24 a1.talk() 25 a2.talk()
posted on
浙公网安备 33010602011771号