一、什么是面向对象
面向对象编程是一种编程方式,使用“类”和“对象”来实现,所以,面向对象编程就是对“类”和“对象”的使用。
面向对象编程 核心就是“对象”二字,“对象”是特征与技能的结合体。“类”则是一个模板,模板里可以包含多个方法(函数),方法可以实现各种功能。对象则是根据模板创建的实例,通过实例“对象”可以执行“类”中的方法,每个“对象”都拥有相同的方法,但是每个“对象”的数据可能并不相同
优点是:解决了程序的扩展性。对某一个对象单独修改,会立刻反映到整个体系中,如对游戏中一个人物参数的特征和技能修改都很容易。
缺点:
1. 编程的复杂度远高于面向过程,不了解面向对象而立即上手基于它设计程序,极容易出现过度设计的问题。一些扩展性要求低的场景使用面向对象会徒增编程难度。
2.无法向面向过程的程序设计流水线式的可以很精准的预测问题的处理流程与结果。
二、“类”’、“对象”和方法
在Python中,定义类是通过class
关键字,class
后面紧接着是类名,类名通常是大写开头的单词,紧接着是('要继承的类名')
,表示该类是从哪个类继承下来的,通常如果没有合适的继承类,就使用object
类,这是所有类最终都会继承的类,也可以不写。
class MyClass(): # 创建类 def func(self): # 定义方法 pass obj1=MyClass() # 根据MyClass创建对象
类中定义的方法,和以前定义函数一样,都是用来实现某种功能的,不过定义方法的时候必须传至少一个参数(self),代表创建的对象,而函数则不需要
class MyClass(): def func(self,str): print(self,str)obj = MyClass() #self是哪个对象调用 self就是那个对象print(obj) #<__main__.MyClass object at 0x02786570>obj.func('test') #<__main__.MyClass object at 0x02786570>
三、面向对象三大特性,封装、继承和多态
1、封装
从封装本身的意思去理解,封装就好像是拿来一个麻袋,把小猫,小狗,小王八,还有alex一起装进麻袋,然后把麻袋封上口子。照这种逻辑看,封装=‘隐藏’,这种理解是相当片面的。
class A: def __init__(self,name): # 构造函数,初始化数据, self.name=name # 封装数据 def f1(self): print(self.name) # 通过self获取封装的数据 a=A('jason')a.f1() #通过对象获取封装数据
在python中用双下划线开头的方式将属性隐藏起来(设置成私有的)
#其实这仅仅这是一种变形操作且仅仅只在类定义阶段发生变形#类中所有双下划线开头的名称如__x都会在类定义时自动变形成:_类名__x的形式:class A: __N=0 #类的数据属性就应该是共享的,但是语法上是可以把类的数据属性设置成私有的如__N,会变形为_A__N def __init__(self): self.__X=10 #变形为self._A__X def __foo(self): #变形为_A__foo print('from A') def bar(self): self.__foo()#只有在类内部才可以通过__foo的形式访问到.# print(A.__N) #报错print(A._A__N)#A._A__N是可以访问到的,#这种,在外部是无法通过__x这个名字访问到。
这种变形需要注意的是:
1.这种机制也并没有真正意义上限制我们从外部直接访问属性,知道了类名和属性名就可以拼出名字:_类名__属性,然后就可以访问了,如a._A__N,即这种操作并不是严格意义上的限制外部访问,仅仅只是一种语法意义上的变形,主要用来限制外部的直接访问。
2.变形的过程只在类的定义时发生一次,在定义后的赋值操作,不会变形
3.在继承中,父类如果不想让子类覆盖自己的方法,可以将方法定义为私有的
#把fa定义成私有的,即__fa>>> class A:... def __fa(self): #在定义时就变形为_A__fa... print('from A')... def test(self):... self.__fa() #只会与自己所在的类为准,即调用_A__fa... >>> class B(A):... def __fa(self):... print('from B')... >>> b=B()>>> b.test()from A
2、继承
继承是一种创建新类的方式,新建的类可以继承一个或多个父类(python支持多继承),父类又可称为基类或超类,新建的类称为派生类或子类。
子类会“”遗传”父类的属性,从而解决代码重用问题
class ParentClass1: #定义父类 passclass ParentClass2: #定义父类 passclass SubClass1(ParentClass1): #单继承,基类是ParentClass1,派生类是SubClass passclass SubClass2(ParentClass1,ParentClass2): #python支持多继承,用逗号分隔开多个继承的类 pass
查看继承
>>> SubClass1.__bases__ #__base__只查看从左到右继承的第一个子类,__bases__则是查看所有继承的父类(,)>>> SubClass2.__bases__( , )
在开发程序的过程中,如果我们定义了一个类A,然后又想新建立另外一个类B,但是类B的大部分内容与类A的相同时
我们不可能从头开始写一个类B,这就用到了类的继承的概念。
通过继承的方式新建类B,让B继承A,B会‘遗传’A的所有属性(数据属性和函数属性),实现代码重用
==========================第一部分例如 猫可以:喵喵叫、吃、喝、拉、撒 狗可以:汪汪叫、吃、喝、拉、撒如果我们要分别为猫和狗创建一个类,那么就需要为 猫 和 狗 实现他们所有的功能,伪代码如下: #猫和狗有大量相同的内容class 猫: def 喵喵叫(self): print '喵喵叫' def 吃(self): # do something def 喝(self): # do something def 拉(self): # do something def 撒(self): # do somethingclass 狗: def 汪汪叫(self): print '喵喵叫' def 吃(self): # do something def 喝(self): # do something def 拉(self): # do something def 撒(self): # do something==========================第二部分上述代码不难看出,吃、喝、拉、撒是猫和狗都具有的功能,而我们却分别的猫和狗的类中编写了两次。如果使用 继承 的思想,如下实现: 动物:吃、喝、拉、撒 猫:喵喵叫(猫继承动物的功能) 狗:汪汪叫(狗继承动物的功能)伪代码如下:class 动物: def 吃(self): # do something def 喝(self): # do something def 拉(self): # do something def 撒(self): # do something# 在类后面括号中写入另外一个类名,表示当前类继承另外一个类class 猫(动物): def 喵喵叫(self): print '喵喵叫' # 在类后面括号中写入另外一个类名,表示当前类继承另外一个类class 狗(动物): def 汪汪叫(self): print '喵喵叫'==========================第三部分#继承的代码实现class Animal: def eat(self): print("%s 吃 " %self.name) def drink(self): print ("%s 喝 " %self.name) def shit(self): print ("%s 拉 " %self.name) def pee(self): print ("%s 撒 " %self.name)class Cat(Animal): def __init__(self, name): self.name = name self.breed = '猫' def cry(self): print('喵喵叫')class Dog(Animal): def __init__(self, name): self.name = name self.breed='狗' def cry(self): print('汪汪叫')# ######### 执行 #########c1 = Cat('小白家的小黑猫')c1.eat()c2 = Cat('小黑的小白猫')c2.drink()d1 = Dog('胖子家的小瘦狗')d1.eat()使用继承来重用代码比较好的例子
3、多态
多态指的是同一种事物的多种状态:水这种事物有多种不同的状态:冰,水蒸气
多态性的概念指出了对象如何通过他们共同的属性和动作来操作及访问,而不需考虑他们具体的类。
冰,水蒸气,都继承于水,它们都有一个同名的方法就是变成云,但是冰.变云(),与水蒸气.变云()是截然不同的过程,虽然调用的方法都一样
class H2o: def __init__(self,name,temperature): self.name = name self.temperature = temperature def Water_change(self): if self.temperature > 0 and self.temperature < 100: print("%s 现在是液态水" %self.name) elif self.temperature > 100: print("%s 现在是水蒸气" % self.name) elif self.temperature < 0: print("%s 现在水结冰了" % self.name)class Water(H2o): passclass Ice(H2o): passclass Steam(H2o): passw1 = Water('水',20)i1 = Ice('冰',-20)s1 = Steam('水蒸气',1000)def func(obj): obj.Water_change()func(w1) #水 现在是液态水func(i1) #冰 现在水结冰了func(s1)#水蒸气 现在是水蒸气