Python中面向对象的特征有哪些
这篇文章给大家分享的是有关Python中面向对象的特征有哪些的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。
面向对象三大特征介绍封装(隐藏):隐藏对象的属性和实现细节,知对外提供必要的方法。
继承:让子类拥有父类特征,提高了代码的重用性。从设计上是一种增量进化,原有父类设计不变的情况下,可以增加新的功能,或者改进 已有的算法。
多态:一个方法调用由于对象不同会产生不同的行为。
继承继承是代码复用的一个非常重要的手段,已有的类,我们称为“父类或者基类”,新的类,我们称为“子类或者派生类”。
语法格式Python 支持多重继承,一个子类可以继承多个父类。继承的语法格式如下:
class 子类类名(父类 1[,父类 2,…]):
 类体
如果在类定义中没有指定父类,则默认父类是 object 类。也就是说,object 是所有类的父 类,里面定义了一些所有类共有的默认实现,比如:new()。
定义子类时,必须在其构造函数中调用父类的构造函数。调用格式如下:
父类名.init(self, 参数列表)
#测试继承的基本使用classPerson():def__init__(self,name,age):self.name=nameself.__age=age#私有属性defprint_name(self):print(self.name)classStudent(Person):def__init__(self,name,age,id):Person.__init__(self,name,age)self.id=idstu=Student('sherry',24,'2017')stu.print_name()print(Student.mro())#查看类的继承层次结构print(dir(stu))#打印所有方法和属性print(stu._Person__age)#继承于父类的私有属性的访问输出:sherry[<class'__main__.Student'>,<class'__main__.Person'>,<class'object'>]['_Person__age','__class__','__delattr__','__dict__','__dir__','__doc__','__eq__','__format__','__ge__','__getattribute__','__gt__','__hash__','__init__','__init_subclass__','__le__','__lt__','__module__','__ne__','__new__','__reduce__','__reduce_ex__','__repr__','__setattr__','__sizeof__','__str__','__subclasshook__','__weakref__','id','name','print_name']24
1.类成员的继承和重写 成员继承:子类继承了父类除构造方法之外的所有成员,包括方法,属性,私有方法,私有属性,只不过私有方法和属性不能直接访问。
2.方法重写:子类可以重新定义父类中的方法,这样就会覆盖父类的方法,也称为“重写”
#重写父类方法的测试classPerson():def__init__(self,name,age):self.name=nameself.__age=age#私有属性defprint_name(self):print(self.name)classStudent(Person):def__init__(self,name,age,id):Person.__init__(self,name,age)self.id=iddefprint_name(self):'''重写了父类的方法'''print('mynameis',self.name)stu=Student('sherry',24,'2017')stu.print_name()输出:mynameissherry查看类的继承层次结构
通过类的方法mro()或者类的属性__mro__可以输出这个类的继承层次结构。
classPerson():def__init__(self,name,age):self.name=nameself.__age=age#私有属性defprint_name(self):print(self.name)classStudent(Person):def__init__(self,name,age,id):Person.__init__(self,name,age)self.id=iddefprint_name(self):'''重写了父类的方法'''print('mynameis',self.name)#stu=Student('sherry',24,'2017')print(Student.mro())输出:[<class'__main__.Student'>,<class'__main__.Person'>,<class'object'>]object根类
object 类是所有类的父类,因此所有的类都有 object 类的属性和方法。
dir()查看对象属性#测试继承的基本使用classPerson():def__init__(self,name,age):self.name=nameself.__age=age#私有属性defprint_name(self):print(self.name)classStudent(Person):def__init__(self,name,age,id):Person.__init__(self,name,age)self.id=iddefprint_name(self):'''重写了父类的方法'''print('mynameis',self.name)obj=object()stu=Student('sherry',24,'2017')print(dir(obj))print(dir(stu))输出:['__class__','__delattr__','__dir__','__doc__','__eq__','__format__','__ge__','__getattribute__','__gt__','__hash__','__init__','__init_subclass__','__le__','__lt__','__ne__','__new__','__reduce__','__reduce_ex__','__repr__','__setattr__','__sizeof__','__str__','__subclasshook__']['_Person__age','__class__','__delattr__','__dict__','__dir__','__doc__','__eq__','__format__','__ge__','__getattribute__','__gt__','__hash__','__init__','__init_subclass__','__le__','__lt__','__module__','__ne__','__new__','__reduce__','__reduce_ex__','__repr__','__setattr__','__sizeof__','__str__','__subclasshook__','__weakref__','id','name','print_name']str()方法的重写
object 有一个__str__()方法,用于返回一个对于“对象的描述”,对应于内置函数 str()。经常用于 print()方法,帮助我们查看对象的信息。str()可以重写。
classPerson():def__init__(self,name,age):self.name=nameself.__age=age#私有属性defprint_name(self):print(self.name)def__str__(self):return'name:{0}age:{1}'.format(self.name,self.__age)p=Person('sherry',24)print(p)输出:name:sherryage:24多重继承
Python 支持多重继承,一个子类可以有多个“直接父类”。这样,就具备了“多个父 类”的特点。但是由于,这样会被“类的整体层次”搞的异常复杂,尽量避免使用。(java不支持多重继承)
classA():passclassB():passclassC(A,B):passprint(C.mro())输出:[<class'__main__.C'>,<class'__main__.A'>,<class'__main__.B'>,<class'object'>]MRO()
Python 支持多继承,如果父类中有相同名字的方法,在子类没有指定父类名时,解释器将 “从左向右”按顺序搜索。
classA():passclassB():passclassC(A,B):passprint(C.mro())输出:[<class'__main__.C'>,<class'__main__.A'>,<class'__main__.B'>,<class'object'>]super()获得父类定义
在子类中,如果想要获得父类的方法时,我们可以通过 super()来做。super()获得父类的定义(不是获得父类的对象)。
#测试super()classA():defsay(self):print('aa')classB(A):defsay(self):super().say()#调用父类方法A.say(self)#调用父类方法print('bb')b=B()b.say()输出:aaaabb多态
多态(polymorphism)是指同一个方法调用由于对象不同可能会产生不同的行为。
关于多态要注意以下 2 点:
1.多态是方法的多态,属性没有多态。
2.多态的存在有 2 个必要条件:继承、方法重写。
#多态classMan():defeat(self):print('eat!')classChinese(Man):defeat(self):print('eatwithchopsticks')classEnglish(Man):defeat(self):print('eatwithfork')classIndian(Man):defeat(self):print('eatwithhand')defmanEat(m):ifisinstance(m,Man):m.eat()else:print('cannoteat!')manEat(Man())manEat(Chinese())manEat(English())manEat(Indian())输出:eat!eatwithchopstickseatwithforkeatwithhand特殊方法和重载运算符
python重的运算符实际上是通过调用对象的特殊方法实现的。
a=20b=30print(a+b)print(a.__add__(b))输出:5050
常见的特殊方法:
每个运算符实际上都对应了相应的方法:
#测试运算符重载classPerson():def__init__(self,name):self.name=namedef__add__(self,other):ifisinstance(other,Person):return'{0}-{1}'.format(self.name,other.name)def__mul__(self,other):ifisinstance(other,int):returnself.name*otherp1=Person('Sherry')p2=Person('Lily')print(p1+p2)print(p1*10)输出:Sherry-LilySherrySherrySherrySherrySherrySherrySherrySherrySherrySherry特殊属性
python中包含了很多双下划线开始和结束的属性,这些是特殊属性,有特殊用法。这里列出常见的特殊属性:
#测试特殊属性classA():defsay(self):print('aa')classB():defsay(self):print('bb')classC(B,A):def__init__(self,name):super().__init__()self.name=namec=C('sherry')print(c.__dict__)#c对象的属性列表print(c.__class__)#c对象的类print(C.__bases__)#C类的基类print(C.__mro__)#C类的继承关系print(C.__subclasses__)#C类的子类输出:{'name':'sherry'}<class'__main__.C'>(<class'__main__.B'>,<class'__main__.A'>)(<class'__main__.C'>,<class'__main__.B'>,<class'__main__.A'>,<class'object'>)<built-inmethod__subclasses__oftypeobjectat0x7fefdacc8dd0>对象的浅拷贝和深拷贝
变量的赋值操作
只是形成两个变量,实际还是指向同一个对象。
浅拷贝Python
拷贝一般都是浅拷贝。拷贝时,对象包含的子对象内容不拷贝。因此,源对象 和拷贝对象会引用同一个子对象。
·深拷贝使用
使用copy 模块的deepcopy函数,递归拷贝对象中包含的子对象。源对象和拷贝对象 所有的子对象也不同。
#测试浅拷贝和深拷贝importcopyclassMobilePhone():def__init__(self,cpu,screen):self.cpu=cpuself.screen=screenclassCPU():defcaculate(self):print('cpu:\t',self)classScreen():defshow(self):print('screen:\t',self)m1=MobilePhone(CPU(),Screen())print('测试赋值----')m0=m1print('m1:\t',m1)m1.cpu.caculate()m1.screen.show()print('m0:\t',m0)m0.cpu.caculate()m0.screen.show()print('测试浅复制----')m2=copy.copy(m1)print('m1:\t',m1)m1.cpu.caculate()m1.screen.show()print('m2:\t',m2)m2.cpu.caculate()m2.screen.show()print('测试深复制----')m3=copy.deepcopy(m1)print('m1:\t',m1)m1.cpu.caculate()m1.screen.show()print('m3:\t',m3)m3.cpu.caculate()m3.screen.show()输出:测试赋值----m1:<__main__.MobilePhoneobjectat0x7f8b0d6ed190>cpu:<__main__.CPUobjectat0x7f8b0d6ed130>screen:<__main__.Screenobjectat0x7f8b0d6ed100>m0:<__main__.MobilePhoneobjectat0x7f8b0d6ed190>cpu:<__main__.CPUobjectat0x7f8b0d6ed130>screen:<__main__.Screenobjectat0x7f8b0d6ed100>测试浅复制----m1:<__main__.MobilePhoneobjectat0x7f8b0d6ed190>cpu:<__main__.CPUobjectat0x7f8b0d6ed130>screen:<__main__.Screenobjectat0x7f8b0d6ed100>m2:<__main__.MobilePhoneobjectat0x7f8b0d6a9940>cpu:<__main__.CPUobjectat0x7f8b0d6ed130>screen:<__main__.Screenobjectat0x7f8b0d6ed100>测试深复制----m1:<__main__.MobilePhoneobjectat0x7f8b0d6ed190>cpu:<__main__.CPUobjectat0x7f8b0d6ed130>screen:<__main__.Screenobjectat0x7f8b0d6ed100>m3:<__main__.MobilePhoneobjectat0x7f8b0d6ed280>cpu:<__main__.CPUobjectat0x7f8b0d6ede20>screen:<__main__.Screenobjectat0x7f8b0d6edd30>组合
“is-a”关系,我们可以使用“继承”。从而实现子类拥有的父类的方法和属性。“is-a” 关系指的是类似这样的关系:狗是动物,dog is animal。狗类就应该继承动物类。
“has-a”关系,我们可以使用“组合”,也能实现一个类拥有另一个类的方法和属性。” has-a”关系指的是这样的关系:手机拥有 CPU。 MobilePhone has a CPU。
设计模式_工厂模式实现设计模式是面向对象语言特有的内容,是我们在面临某一类问题时候固定的做法,设计 模式有很多种,比较流行的是:GOF(Goup Of Four)23 种设计模式。当然,我们没有 必要全部学习,学习几个常用的即可。
对于初学者,我们学习两个最常用的模式:工厂模式和单例模式。
工厂模式实现了创建者和调用者的分离,使用专门的工厂类将选择实现类、创建对象进行统一的管理和控制。
#测试工厂模式classCarFactory():defcreatCar(self,brand):ifbrand=='奔驰':returnBenz()elifbrand=='宝马':returnBMW()elifbrand=='比亚迪':returnBYD()else:print('cannotcreate!')classBenz():passclassBMW():passclassBYD():passfactory=CarFactory()c1=factory.creatCar('奔驰')c2=factory.creatCar('宝马')c3=factory.creatCar('比亚迪')设计模式_单例模式实现
单例模式(Singleton Pattern)的核心作用是确保一个类只有一个实例,并且提供一个访问该实例的全局访问点。
单例模式只生成一个实例对象,减少了对系统资源的开销。当一个对象的产生需要比较 多的资源,如读取配置文件、产生其他依赖对象时,可以产生一个“单例对象”,然后永久 驻留内存中,从而极大的降低开销。
#测试单例模式classMySingleton():__obj=None__init_flag=Truedef__new__(cls,*args,**kwargs):ifcls.__obj==None:cls.__obj=object.__new__(cls)#__obj对象只创建一次obj对象就是Mysingleton对象returncls.__objdef__init__(self,name):ifself.__init_flag==True:print('init....')self.name=nameself.__init_flag=Falsea=MySingleton('aa')b=MySingleton('bb')c=MySingleton('cc')print(a)print(a.name)print(b)print(b.name)print(c)print(c.name)输出:init....<__main__.MySingletonobjectat0x7fce0f6e8130>aa<__main__.MySingletonobjectat0x7fce0f6e8130>aa<__main__.MySingletonobjectat0x7fce0f6e8130>aa工厂模式和单例模式的整合使用
#测试工厂模式和单例模式的混合使用classCarFactory():__obj=None__init_flag=Truedef__new__(cls,*args,**kwargs):ifcls.__obj==None:cls.__obj=object.__new__(cls)returncls.__objdef__init__(self):ifself.__init_flag:print('initfactory')self.__init_flag=FalsedefcreatCar(self,brand):ifbrand=='奔驰':returnBenz()elifbrand=='宝马':returnBMW()elifbrand=='比亚迪':returnBYD()else:print('cannotcreate!')classBenz():passclassBMW():passclassBYD():passfactory=CarFactory()c1=factory.creatCar('奔驰')c2=factory.creatCar('宝马')c3=factory.creatCar('比亚迪')factory2=CarFactory()print(factory)print(factory2)输出:initfactory<__main__.CarFactoryobjectat0x7fd286eecc10><__main__.CarFactoryobjectat0x7fd286eecc10>
感谢各位的阅读!关于“Python中面向对象的特征有哪些”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。