Python成长之路 面向对象
面相对象
关于面向对象的定义和标准在网上有很多,作为一个初学者我就不在这献丑了。
面向对象编程相对于面相过程编程和函数式编程来说,面相对象编程编程利用类和对象创建各种模型来实现对现实世界的描述,它使得程序的维护和扩展变的更简单,并大大提高了程序的开发效率,另外它使我们更好的理解代码逻辑,使得团队的开发更容易。对于面向对象来说在python中一切皆为对象。
面向过程编程:就是我们做一件事,我们先要做什么在做什么,我们的代码就会一步步的实现我们要的功能,但是当我们在重复做这件事的时候这个功能我们就要再写一次,这样就会出错。比如现在的送餐员,他先要到某个店中拿外卖、再根据外卖上的地址送到指定的地方、到了地方后要打电话给定外卖的人,整一个个的动作我们使用面向过程编程,那我们就要先实现取外卖、送到指定地点、打电话、把外卖送到订餐人手上这一系列的功能。一个送外卖的不可能就送一个外卖,同样也不可能只送一个地方一个人、所以我们下次再送不同的人的时候又要写差不多的功能,这样就会出错。
面相对象编程:我们可以定义一个送快外卖的人我们赋予他取外卖、根据地址送到指定位置、再打电话、在等待等等一些关于送餐员的所有功能,当我们要送餐的时候我们就创建出一个这个送外卖人的实例出来,然后让他去做这些事情。
面向对象的几个核心
Class 类
一个类即是对一类拥有相同属性的对象的抽象、蓝图、原型。在类中定义了这些对象的都具备的属性(variables(data))、共同的方法
Object 对象
一个对象即是一个类的实例化后实例,一个类必须经过实例化后方可在程序中调用,一个类可以实例化多个对象,每个对象亦可以有不同的属性,就像人类是指所有人,每个人是指具体的对象,人与人之前有共性,亦有不同
Encapsulation 封装
在类中对数据的赋值、内部调用对外部用户是透明的,这使类变成了一个胶囊或容器,里面包含着类的数据和方法
Inheritance 继承
一个类可以派生出子类,在这个父类里定义的属性、方法自动被子类继承
Polymorphism 多态
多态是面向对象的重要特性,简单点说:“一个接口,多种实现”,指一个基类中派生出了不同的子类,且每个子类在继承了同样的方法名的同时又对父类的方法做了不同的实现,这就是同一种事物表现出的多种形态。
面向对象的相关介绍
类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用
数据成员:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用
方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
实例变量:定义在方法中的变量,只作用于当前实例的类
实例化:创建一个类的实例,类的具体对象
方法:类中定义的函数
类的定义和实例化对象
类的定义使用class来定义的,定义类分为新式类和经典类
新式类的定义方式为"class ClassName(object):"
经典类的定义方式为"class ClassName:"
新式类和经典类的区别:
新式类继承了object,经典类不需要
多继承在python2中新式类的时候是深度优先,而经典类是广度优先
在python3中不管新式类还是经典类都是广度优先
#python2.x class A: pass class B(A): pass class C(A): pass class D(B,C): pass #多继承的顺序为 D->B->C->A 深度优先 class A(object): pass class B(A): pass class C(A): pass class D(B,C): pass #多继承的顺序为:D->B->A->C 广度优先 #python3中多继承的顺序都是:D->B->A->C 广度优先
类的定义和实例化对象
# class Dog(object): # """ # 定义一个狗的类 # """ # print('hello dog') # # # d = Dog() #这个就是实例化类。d就是类Dog的实例化 # class Dog(object): family = 'Canidae' #这个是类变量在整个实例化对象中是公用的 def __init__(self,name):#__init__方法是构造函数实例化对象时自动执行 # self为实例化的对象本身 即即将被实例化的对象obj self.name = name #这个就是实例化变量 print("The dog's name is %s"%self.name) d = Dog('小黑')#实例化类的时候自动执行__init__ #运行的结果为'The dog's name is 小黑' print(d.name) #调用对象的name属性
当实例化变量和类变量名一样的时候我们在实例化对象后调用的时候调用的是实例化变量,所以说在有相同的变量名时,实例化变量优先类变量。
class MyCalss(object): cn= '中国' def __init__(self,cn): self.cn = cn d = MyCalss('日本') print(d.cc) #结果是‘日本’
类中的方法
在类的内部,使用def关键字定义的一个方法,与一般的函数不同的是类方法必须包含参数self,且第一个参数就是self,self代表的是类的实例。
class Car(object): """ 汽车模型 """ def __init__(self,name,car_type):#定义构造函数 self.name = name self.car_type = car_type def back(self):#定义类的方法必须带参数self这个self代表的是类的实例 print('当前模式为倒退') def advance(self):#定义类的方法 print('当前模式为前进')
在类中除了有构造函数之外还有一个析构函数
它的作用是在实例释放、销毁或程序结束的时候会自动执行。通常用于一些收尾工作、如关闭数据库连接。析构函数的定义为__del__(self)
类的私有属性和方法
类的私有属性和方法就是正常的属性和方法是以两个下划线开头
私有属性:__private_attrs申明此为私有属性,该属性不能在类的外部被调用,只能在类的内部被调用,调用的语法为self.__private_attrs
私有方法:__private_methods(self),该方法只能内部调用不可以外部调用,调用的方式为self.__private_methods()
class Car(object): """ 汽车模型 """ __place = 'China' def __init__(self,name,car_type):#定义构造函数 self.name = name self.car_type = car_type def back(self):#定义类的方法必须带参数self这个self代表的是类的实例 print('当前模式为倒退') print('私有属性:',self.__place) print('私有方法:',end=''),self.__advance() def __advance(self):#定义私有方法 print('当前模式为前进') dazhong = Car('大众','轿车')#实例化类 dazhong.back()#调用类中的方法 #dazhong.__advance() #这个调用会报错,错误提示为 AttributeError: 'Car' object has no attribute '__advance' #print(dazhong.place)#这个调用会报错,错误提示为 AttributeError: 'Car' object has no attribute 'place'
封装
对于面向对象的封装来说,其实就是使用构造方法将内容封装到对象中,然后通过对象直接或者self间接获取被封装的内容。
继承与多继承
当类之间基本相同,只有部分功能不同的时候使用继承。
继承是两个类或者多个类之间的父子关系,子类继承所有父类共有实例变量和方法。
class People(object): def __init__(self,name,sex,age,language): self.name = name self.sex = sex self.age = age self.language = language def speak(self): print('%s 会说 %s' % (self.name,self.language)) class Students(People): def __init__(self,name,sex,age,language,school): super(Students,self).__init__(name,sex,age,language) #上面的是调用父类的构造函数 self.school = school student2 = Students('Tom','M',22,'Chinese','一中') student2.speak() #执行的结果Tom 会说 Chinese #如果想要覆盖父类的方法那么就在子类中重新写这个方法。 class Teachers(People): def __init__(self,name,sex,age,language,school): super(Students,self).__init__(name,sex,age,language) #上面的是调用父类的构造函数 self.school = school def speak(self): print('%s 在教 %s'%(self.name,self.language)) teacher2 = Students('Tom','M',22,'Chinese','一中') teacher2.speak()#调用类中的方法 #执行的结果Tom 在教 Chinese
多继承
一个类同时继承多个类,与多个类具有继承关系,这个类可以调用所有父类中的方法和类中变量,如果子类中没有构造函数就会继承父类的构造函数,继承的方式为广度优先。
因为Python3中不管新式类还是经典类都为广度优先。而python2新式类则为深度优先,而经典类则为广度优先
# class A(object): # def __init__(self): # print("A") # # class B(A): # def __init__(self): # print('B') # # class C(A): # def __init__(self): # print('C') # # class D(B,C): # pass # # t = D() #结果为B所以它继承的是B的构造函数 #如果子类没有构造函数他就会继承父类中的构造函数, #继承的父类是按照广度优先 # class A(object): # def __init__(self): # print("A") # # class B(A): # pass # # class C(A): # def __init__(self): # print('C') # # class D(B,C): # pass # # t2 = D() #结果为C 所以继承的是C的构造函数 class A: def __init__(self): print("A") class B(A): pass class C(A): def __init__(self): print("A") class D(B,C): pass t3 = D() #结果为A 继承的是A的构造函数
多态
多态指的是一类事物有多种形态,也就是一种接口,多种实现。用来实现接口的重用。
python中没有多态的语法,但是它能够实现多态的功能。
class Animal(object): def __init__(self, name): self.name = name @staticmethod #这个就相当于实现了一个借口多种实现 def talk(obj): # 一个接口,多种形态 obj.talk() class Cat(Animal): def talk(self): print('%s: 喵喵喵!' % self.name) class Dog(Animal): def talk(self): print('%s: 汪!汪!汪!' % self.name) c1 = Cat('xiaobai') d1 = Dog('xiaohei') Animal.talk(c1) Animal.talk(d1)
关于基础的面向对象就介绍到这里,如果有什么说错了或者说的不好欢迎指出来。
相互学习,相互进步。