目录
一、面向过程与面向对象
面向过程:分析出解决问题的步骤,并且用代码一步一步的实现出来,类似于一个流水线,代表语言是C语言
面向对象:把要解决的问题划分为多个模块(对象),依靠各个对象之间的交互来解决问题,代表语言的Python,C++,Java等
二、类和对象
面向对象程序设计的一个关键性观念是将数据以及对数据的操作封装在一起,组成一个相互依存、不可分割的整体,即对象。
对象的行为称为成员方法(函数),对象的属性称为成员属性(数据成员),两者统称为类的成员。
对于相同类型的对象进行分类、抽象后,得出共同的特征而形成了类,面向对象程序设计的关键就是如何合理地定义和组织这些类以及类之间的关系。
在Python中一切皆对象,无论是整数还是列表都是对象,比如你可以打点调用它们拥有的方法。
三、类中的属性与方法
(1)类的属性
类的属性分为类属性的实例属性两类,其中又分为公有和私有
1.类属性
属于类,可以通过类名或者对象名调用
2.实例属性
属于对象,只能通过对象名调用。
我们可以从继承的角度理解。因为对象是类的“孩子”,且只有一个父亲,所以对象可以调用类的全部属性。但类就不行了,因为它有很多孩子,不知道要调用哪一个的。
(2)类的方法
在类中定义的方法大之可以分为四类:公共方法、私有方法、静态方法和类方法
1.公有方法
可以通过对象名直接调用,是我们最常用到的方法,属于对象
2.私有方法
不可以通过对象名直接调用,只能用特定的方法调用,属于对象。
3.静态方法
定义时需要使用修饰器@staticmethod修饰,属于类,不需要实例。一般不会在静态方法中调用类的属性和方法。
4.类方法
定义时需要使用修饰器@classmethod修饰,且第一个参数必须是当前类,一般写为“cls”。类方法用来传递类的属性和方法,不能传递实例的属性和方法,可以通过类名或者对象来调用它。
(3)举例说明
class Root:
# 类属性
cls_num = 1 # 公有
__total = 0 # 私有
# 构造方法
def __init__(self, v):
# 实例属性
print('这是构造方法')
self.num = v # 公有
self.__value = v # 私有
# 公有方法
def show(self):
print('这是公有方法')
# 私有方法
def __change(self, v):
print('这是私有方法')
# 类方法
@classmethod
def classShowTotal(cls):
print('这是类方法')
# 静态方法
@staticmethod
def staticShowTotal():
print('这是静态方法')
# 实例化一个对象
r = Root(3)
# 访问类属性
# print(Root.__total,r.__total) #不可访问
print(Root.cls_num, r.cls_num)
# 访问实例属性
# print(Root.num) #不可访问
print(r.num)
# 调用公有方法
r.show() # 通过对象调用
Root.show(r) # 通过类调用
# 调用私有方法 都不成
# Root.__change(r)
# r.__change()
# 调用静态方法
r.staticShowTotal() # 通过对象调用
Root.staticShowTotal() # 通过类调用
# 调用类方法
r.classShowTotal() # 通过对象调用
Root.classShowTotal() # 通过类调用
四、方法属性
这是Python3才开始支持的,通俗地说就是把函数当作属性来访问。可以将属性定义为只读、可读写、可读写和删除三种类型
(1)只读
class Test:
def __init__(self, value):
self.__value = value
@property
def value(self): # 只读,无法修改和删除
return self.__value
@property
def __num(self):
return self.__value
t = Test(2)
print(t.value)
print(t.__num) # 不可访问。
(2)可读写
class Test:
def __init__(self, value):
self.__value = value
def __get(self): # 可读
return self.__value
def __set(self, v):
self.__value = v # 可写
value = property(__get, __set) # 可读写
def show(self):
print(self.__value)
t = Test(2)
print(t.value)
t.value = 5
print(t.value)
(3)可读可写可删除
class Test:
def __init__(self, value):
self.__value = value
def __get(self):
return self.__value
def __set(self, v):
self.__value = v
def __del(self):
del self.__value
value = property(__get, __set, __del) # 可读可写可删除
t = Test(3)
print(t.value)
t.value = 5
print(t.value)
del t.value # 删除t.value
五、魔法方法
Python中有很多魔法方法,一般都是以双下划线开头和结尾。比如我们常用的构造方法__init__()和析构方法__del__()就属于魔法方法。下面列出了一些常见的魔法方法。
方法 | 功能说明 |
__new__() | 类的静态方法,用于确定是否要创建对象 |
__init__() | 构造方法,创建对象时自动调用 |
__del__() | 析构方法,释放对象时自动调用 |
__add__() | + |
__sub__() | - |
__mul__() | * |
__truediv__() | / |
__floordiv__() | // |
__mod__() | % |
__pow__() | ** |
__eq__() | == |
__ne__() | != |
__lt__() | < |
__le__() | <= |
__gt__() | > |
__ge__() | >= |
__lshift__() | << |
__rshift__() | >> |
__and__() | & |
__or__() | | |
__invert__() | ~ |
__xor__() | ^ |
__iadd__()、__isub__() | +=、-=,很多其他运算符也有与之对应的复合赋值运算符 |
__pos__() | 一元运算符+,正号 |
__neg__() | 一元运算符-,负号 |
__contains__ () | 与成员测试运算符in对应 |
__radd__() | 反射加法,与普通加法功能相同,但操作数的位置或顺序相反 |
__rsub__ | 反射减法,与普通减法功能相同,但操作数的位置或顺序相反 |
__abs__() | 与内置函数abs()对应 |
__bool__() | 与内置函数bool()对应,要求该方法必须返回True或False |
__bytes__() | 与内置函数bytes()对应 |
__complex__() | 与内置函数complex()对应,要求该方法必须返回复数 |
__dir__() | 与内置函数dir()对应 |
__divmod__() | 与内置函数divmod()对应 |
__float__() | 与内置函数float()对应,要求该该方法必须返回实数 |
__hash__() | 与内置函数hash()对应 |
__int__() | 与内置函数int()对应,要求该方法必须返回整数 |
六、面向对象的三大特征
(1)封装
简单理解就是把实现某些功能的代码封装到一个类或函数中,然后给外部提供一个调用接口。比如创建一个Person类,其给外界留下一个接口Person()可以创建一个Person对象,这个对象可以吃饭,可以行走,可以睡觉,但是外界并不知道这些动作是怎么完成的。
(2)继承
子类继承父类,得到父类的全部方法和属性,有利于实现多态和代码的复用。继承分为单继承和多继承两种。
1.单继承
子类只有继承一个父类
class Person():
sleep = '躺着睡'
def __init__(self):
print('父亲初始化成功')
def getsleep(self):
print(self.sleep)
class Person_son(Person):
eat = '用筷子吃'
def __init__(self):
print('儿子初始化成功')
def geteat(self):
print(self.eat)
father = Person()
son = Person_son()
father.getsleep()
son.getsleep()
son.geteat()
2.多继承
顾名思义,子类继承多个父类
class Person1():
sleep = '躺着睡'
def __init__(self):
print('父亲1号初始化成功')
def getsleep(self):
print(self.sleep)
class Person2():
exercise = '跑步'
def __init__(self):
print('父亲2号初始化成功')
def getexercise(self):
print(self.exercise)
class Person_son(Person1, Person2):
eat = '用筷子吃'
def __init__(self):
print('儿子初始化成功')
def geteat(self):
print(self.eat)
father1 = Person1()
father2 = Person2()
son = Person_son()
father1.getsleep()
father2.getexercise()
son.getsleep()
son.getexercise()
son.geteat()
3.函数重写
子类除了可以继承父类的方法之外,还可以重写父类的方法,这是实现多态的一个重要手段。
class Person():
sleep = '躺着睡'
def __init__(self):
print('父亲初始化成功')
def getsleep(self):
print(self.sleep)
class Person_son(Person):
eat = '用筷子吃'
def __init__(self):
print('儿子初始化成功')
def geteat(self):
print(self.eat)
def getsleep(self):
print('我会' + self.sleep)
father = Person()
son = Person_son()
father.getsleep()
son.getsleep()
(3)多态
为不同数据类型的实体提供统一的接口就是多态。简单来说就是一个函数demo,其可以接收一个int型变量,也可以接收一个float型变量。
由于本人水平有限,文中不当之处还请各位大佬不吝赐教!