l 面向对象编程思想
面向对象的编程核心是对象,在理解对象为何物时,必须把自己当作上帝,因为在上帝眼中世间存在的万物皆为对象,不存在的也可以创造出来。对象是特征和技能的结合,其中特征和技能分别对应对象的数据属性和方法属性。
与面向过程的方法相比,面向对象不再局限于计算机的机器本质,而更加侧重于对现实世界的模拟。面向过程的方法中,有一套设计严格的操作顺序,有一个类似中央控制器的角色来进行统一调度;而面向对象的方法中,并没有明确的中央控制的角色,也不需要指定严格的操作顺序,而是设计了很多对象,并且指定了这些对象需要完成的任务,以及这些对象如何对外界的刺激做出反应。
如果说面向过程像一条流水生产线,那么面向对象就像是一个足球队。没有哪个人能够在一场比赛开始的时候,就精确指定每个队员的每一次跑动,每一次出脚,每一次传球。。。。。。而只能指定队员的角色(前锋、中场、后卫、门将),然后由队员门自己根据情况做出反应。所以世界上有两个一样的生产线,但绝对不会存在两场一模一样的比赛。
面向对象这种对现实世界的模拟的思想,其本质上就是“人的思想”,这是一个质的飞跃,意味着程序员可以按照人的思想来观察、分析、设计系统。
什么叫做“人的思想”?你可以放下书本,关上电脑,站起来,环顾四周,你看到的是什么?可能是你的同事、桌子、墙、电脑、花盆;或者是电话、窗子、书本。。。。。。怎么样,这些都是“对象”吧?除了观察目标聚焦于“对象”外,当我们观察人类世界各种事情的运作的时候,我们也不知不觉的聚焦于“对象”。例如,一个公司的运作,由董事长、经理、主管、员工等人分工合作,根据不同的任务或者外界竞争而去做各种各样的事情。
人大部分的时间都是按照面向对象的方式进行思考的,而且人类世界主要也是按照面向对象的方式进行运转的,所以说,“面向对象”其实更加符合人的思维习惯。
面向过程中有“程序=算法+数据结构”的经典总结,面向对象也有类似的总结:“程序=对象 + 交互”。其中对象就是具体存在的事物,而交互则是事物之间的相互作用、互动等。
如下是一张医院的组织结构图,形象的说明了面向对象的处理方式:
l 封装的意义和操作过程
封装就是将对象的相关信息和行为捆绑成一个单元,即将对象封装为一个具体的类。将对象敏感的数据封装在类的内部,不让外界直接访问,而是通过当前类提供的set/get方法间接访问数据,此时就可以在set/get中添加限制条件进行访问数据的控制。
在封装过程中还能将方法隐藏起来,使其与变量的使用方法一样,如:
高级封装使用@property和@get_method.setter注解,来注释set/get方法,隐藏set/get方法的实现,让方法的使用方式和属性一致
class Animal:
def __init__(self,name,age):
self.__name=name
self.__age=age
@property
def name(self):
return self.__name
@name.setter
def name(self,n):
self.__name=n
def age(self):
return self.__age
def age(self,a):
if (a>=0)and(a<=20):
self.__age=a
else:
print("年龄不合法")
a=Animal("cat",18)
a.name="tom"#设置值
print(a.name)
a.age=22
print(a.age)
l 继承的意义和操作过程
一个类型继承另一个类型,当前类型就会拥有另一个类型的公共的属性和方法,达到代码的重复使用的目的。
继承的语法:
class 类型(被继承的类型):
pass
继承中出现的术语:
父类:被继承的类,也称为基类、超类
子类:当前类,也称为派生类
子类继承父类,体现的时A is a B的关系
子类继承父类,就可以使用父类中所有的公开的属性和方法
继承链
A继承B,B继承C,C继承D
A直接继承了B,间接继承了C,D;此时A创建的对象,可以同时使用B,C,D中所有公开的属性和方法
class God:
def __init__(self,name):
self.name=name
def eat(self):
print("玉露琼浆")
class LZS(God):
def drink(self):
print("喝花酒")
zhishen_lu=LZS("鲁智深")
zhishen_lu.eat()
zhishen_lu.drink()
tianpeng = God("天蓬")
tianpeng.eat()
tianpeng.drink()
这个就会报错,因为对象tianpeng实现的类God中没有drink()方法
l 多态的意义和操作过程
首先Python不支持多态,也不用支持多态,python是一种多态语言,崇尚鸭子类型。以下是维基百科中对鸭子类型得论述:
在程序设计中,鸭子类型(英语:duck typing)是动态类型的一种风格。在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由当前方法和属性的集合决定。这个概念的名字来源于由James Whitcomb Riley提出的鸭子测试,“鸭子测试”可以这样表述:
“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”
在鸭子类型中,关注的不是对象的类型本身,而是它是如何使用的。例如,在不使用鸭子类型的语言中,我们可以编写一个函数,它接受一个类型为鸭的对象,并调用它的走和叫方法。在使用鸭子类型的语言中,这样的一个函数可以接受一个任意类型的对象,并调用它的走和叫方法。如果这些需要被调用的方法不存在,那么将引发一个运行时错误。任何拥有这样的正确的走和叫方法的对象都可被函数接受的这种行为引出了以上表述,这种决定类型的方式因此得名。
鸭子类型通常得益于不测试方法和函数中参数的类型,而是依赖文档、清晰的代码和测试来确保正确使用。从静态类型语言转向动态类型语言的用户通常试图添加一些静态的(在运行之前的)类型检查,从而影响了鸭子类型的益处和可伸缩性,并约束了语言的动态特性。
程序在运行的过程中,根据传递的参数的不同,执行不同的函数或者操作不同的代码,这种在运行过程中才确定调用的方式成为运行时多态
class Person:
def __init__(self,name,age,health):
self.name=name
self.age=age
self.health=health
def recure(self):
print("[%s]康复了,当前健康值:%s"%(self.name,self.health))
class Man(Person):
def __init__(self,name,age,health):
Person.__init__(self,name,age,health)
def recure(self):
print("%s德玛西亚!健康了"%self.name)
class Women(Person):
def __init__(self,name,age,health):
Person.__init__(self,name,age,health)
def recure(self):
print("[%s]老娘又回来了,健康了"%self.name)
class Animal:
def __init__(self,name,age,health):
self.name=name
self.age=age
self.health=health
def recure(self):
print("[%s]哈哈哈,终于康复了,当前健康值%s"(self.name,self.health))
class Hospital:
def __init__(self):
self.name="人民医院"
def care(self,person):
#Python 中的isinstance函数,isinstance是Python中的一个内建函数。是用来判断一个对象是否是一个已知的类型。
if isinstance(person, Person):
if person.health > 0 and person.health <= 50:
print("手术......")
person.health += 30
person.recure()
elif person.health > 50 and person.health <= 70:
print("输液......")
person.health += 15
person.recure()
else:
print("健康")
else:
print("mdzz,你是人吗?请出门右转")
hospital=Hospital()
old_wang = Person("王先生", 58, 30)
mrs_li = Women("李夫人", 28, 56)
mr_li = Man("李先生", 30, 60)
# 调用了治疗的方法
hospital.care(old_wang)
hospital.care(mrs_li)
hospital.care(mr_li)
a = Animal("tom", 22, 10)
hospital.care(a)
人民医院.治疗(病人)
当治疗方法在执行的过程中,根据传递的数据的不同,在执行时调用
病人甲(人) 不同的处理代码或者处理函数,来完成治疗效果,动态处理(多态)
病人乙(男人)
病人丙(女人)人的类型 VS 动物类型,不是多态~而是通过if条件判断执行代码
病人丁(动物)人/男人/女人,执行的代码一致【运行过程中,才确定调用谁的方法】