谈面向对象的编程(Python)
(注:本文部分内容摘自互联网,由于作者水平有限,不足之处,还望留言指正。)
今天中秋节,也没什么特别的,寻常日子依旧。
谈谈面向对象吧,什么叫面向对象?
那么问题来了,你有对象吗? 嗯,,,那我可以做你的经纪人吗?
言归正传
对于我来说,从接触到使用python其实有较长一段时间了。要说Python最核心的东西,我想了想,那应该当属面向对象的编程了吧。下面写一点我的理解:
一、面向对象与面向过程的区别
通俗的讲,面向过程是编年史(按照历史年份写下来的的);
面向对象是纪传史(比如说项羽本纪,讲的就是项羽的故事。项羽就是---对象)。
换一种方式讲:
面向过程可以理解为我不停的写函数完成我要的功能。注重函数实现。
面向对象则是我在写这个功能的时候考虑把这个功能分类封装起来。以后我就可以直接拿来用了。注重封装好后调用,不用管
函数怎么实现,只要结果。
举例:
面向过程:
def 吃饭(): def 睡觉(): def 打豆豆(): 吃饭() #比如要吃饭
面向对象:
class 屌丝的一天: def 吃饭(): def 睡觉(): def 打豆豆(): #引入了类的概念 diaosi = 屌丝的一天() diaosi.吃饭()
二、类的概念(class)
类其实是一种数据结构,我们可以用它来定义对象,一个类会包含属性和行为特性.类是现实世界抽象的实体以编程形式出现。类是一个模板,模板中包装了多个“函数”供使用。(Python中一切皆是对象,类也是对象。)
1. 类的成员:字段、方法和属性
i字段
字段包括:普通字段和静态字段,他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同。普通字段属于对象,静态
字段属于类。
class person: height = '173' #静态字段 def __init__(self,weight): self.weight = weight #普通字段 #访问静态字段 print(person.height) #输出173 #访问普通字段 weng = person('60') print(weng.weight) #输出60
由上述代码可以看出普通字段需要通过对象来访问;静态字段通过类访问。
静态字段在内存中只保存一份;普通字段在每个对象中都要保存一份
在上面的类person里面,height是全局变量(在这个类的函数中都生效),而self.weight是局部变量。
ii 方法
方法包括:普通方法、静态方法和类方法。
普通方法:由对象调用;至少一个self参数;执行普通方法时,自动将调用该方法的对象赋值给self;
类方法:由类调用; 至少一个cls参数;执行类方法时,自动将调用该方法的类复制给cls;
静态方法:由类调用;无默认参数;
class person: #定义普通方法 def hello(self): print('普通方法') #定义类方法 @classmethod def haha(cls): print('类方法') #定义静态方法 @staticmethod def hehe(): print('静态方法') weng = person() weng.hello() #调用普通方法 person.haha() #调用类方法 person.hehe() #调用静态方法
III 属性
由属性的定义和调用要注意一下几点:
定义时,在普通方法的基础上添加 @property 装饰器;
定义时,属性仅有一个self参数
调用时,无需括号
方法:foo_obj.func()
属性:foo_obj.prop
属性的定义有两种方式:
装饰器 即:在方法上应用装饰器
静态字段 即:在类中定义值为property对象的静态字段(即property装饰器)
(注:关于装饰器的内容,等我升值加薪再写吧)
三、 构造函数 __init__()
用于初始化类的内容部状态,Python提供的构造函数式 __init__();也就是当该类被实例化的时候就会执行该函数(通过类创造对象时,
自动触发执行)。
class person: def __init__(self,name,age): self.name = name self.age = age weng = person('weng','23')
四、 析构函数 __del__() (用来释放内存的)
当对象在内存中被释放时,自动触发执行。
注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释
器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。
class person: def __init__(self,name,age): self.name = name self.age = age def __del__(self): pass weng = person('weng','23')
接下来是面向对象的三个主要特性:封装、继承、多态
一、封装
就是将内容封装到某个地方,以后再去调用被封装在某处的内容。
class person: def __init__(self,name,age): self.name = name self.age = age weng = person('weng','23') #将内容封装给weng print(weng.age) #调用封装的某处内容
和平时常用的方法十分相似。
二、继承
面向对象中的继承和现实生活中的继承相同,即:子可以继承父的内容。
class dad: def height(self,height): print (height) def weight(self,weight): self.weight = weight class son(dad): #继承了身高、体重,没继承兴趣 def interests(self): print('打游戏') weng = son() weng.height('173') weng.interests()
多继承:
· 是否可以继承多个类
· 如果继承的多个类每个类中都定了相同的函数,那么那一个会被使用呢?
1、Python的类可以继承多个类
2、Python的类如果继承了多个类,那么其寻找方法的方式有两种,分别是:深度优先和广度优先
· 当类是经典类时,多继承情况下,会按照深度优先方式查找
· 当类是新式类时,多继承情况下,会按照广度优先方式查找
经典类和新式类,从字面上可以看出一个老一个新,新的必然包含了跟多的功能,也是之后推荐的写法,从写法上区分的话,如果 当
前类或者父类继承了object类,那么该类便是新式类,否则便是经典类。
class dad: #经典类 pass class son(dad): #经典类 pass class dad1(object): #新式类 pass class son1(dad1): #新式类 pass
下面给出网上的两个例子,供参考:
class D: def bar(self): print('D.bar') class C(D): def bar(self): print('C.bar') class B(D): def bar(self): print('B.bar') class A(B, C): def bar(self): print('A.bar') a = A() a.bar() # 执行bar方法时 # 首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去D类中找,如果D类中么有,则继续去C类中找,如果还是未找到,则报错 # 所以,查找顺序:A --> B --> D --> C # 在上述查找bar方法的过程中,一旦找到,则寻找过程立即中断,便不会再继续找了
class D(object): def bar(self): print('D.bar') class C(D): def bar(self): print('C.bar') class B(D): def bar(self): print('B.bar') class A(B, C): def bar(self): print('A.bar') a = A() a.bar() # 执行bar方法时 # 首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去C类中找,如果C类中么有,则继续去D类中找,如果还是未找到,则报错 # 所以,查找顺序:A --> B --> C --> D # 在上述查找bar方法的过程中,一旦找到,则寻找过程立即中断,便不会再继续找了
三、多态
多态性是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特
性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。
那么,多态的作用是什么呢?我们知道,封装可以隐藏实现细节,使得代码模块化;继承可以扩展已存在的代码模块(类);它们的
目的都是为了——代码重用。而多态则是为了实现另一个目的——接口重用!多态的作用,就是为了类在继承和派生的时候,保证使
用“家谱”中任一类的实例的某一属性时的正确调用。
class Animal(object): def __init__(self, name): self.name = name def talk(self): raise NotImplementedError("Subclass must implement abstract method") class Cat(Animal): def talk(self): print('%s: 喵喵喵!' %self.name) class Dog(Animal): def talk(self): print('%s: 汪!汪!汪!' %self.name) def func(obj): #一个接口,多种形态 obj.talk() c1 = Cat('小苏') d1 = Dog('小江') func(c1) func(d1)
输出结果:
经过此番折腾,我把我面向对象的理解分享完了。而我的对象,她在哪里?哎呀,老铁,扎心了。