面向对象
对象:是指现实中的物体实体化,对象有很过属性(名字、年龄..),也有很多行为(学习、吃饭..),实例即对象。对象同时也是通过类定义的数据结构实例,对象包括两个数据成员(类变量和实例变量)和方法。
实例化:创建一个类的实例,类的具体对象化,实例就是类的实例化,d1 = gog(),d1即为实例
类:拥有相同属性和方法(行为)的对象划为一组,称为类,类是创建对象的工具
方法:类中定义的函数
类变量:类变量定义在类中且在函数体之外,类变量通常不作为实例变量使用
数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据
方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行修改,这个过程叫方法的覆盖,也叫方法的重写
继承:及一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。
Python中的类提供了面向对象编程的所有基本功能:类的继承机制允许多个基类,派生类可以覆盖基类中的任何方法,方法中可以调用基类中的同名方法。
对象可以包含任意数量和类型的数据。
类定义 语法格式
class 类名(继承列表):
"类的文档字符串"
实例方法的定义
类变量的定义
类方法的定义(@classmethod)
静态方法的定义(@staticmethod)
作用:
创建一个类,类用于描述对象的行为和属性,类用于创建此类的一个或者多个对象(实例)类名实质上是变量,它绑定一个类
类实例化后,可以使用其属性,实际上,创建一个类之后,可以通过类名访问其属性
d1 = dog() #调用构造函数创建实例化对象
类对象
类对象支持两种操作:属性引用和实例化。
类对象创建后,类命名空间中的所有命名都是有效属性名,类定义如下所示:
class Myclass: #定义一个自己的类 """一个简单的类实例""" i = 12345 #类变量 def f(self): #定义类的方法 return("你好呀")# 实例化类 用x来绑定以便后面使用,不然用完之后就释放了x = Myclass() # 把一个类变成具体对象的过程叫做实例化(初始化)# 访问类的属性和方法print("Myclass类的属性i为:",x.i)print("Myclass类的方法f为:",x.f())
1 MyClass 类的属性 i 为: 123452 MyClass 类的方法 f 输出为: 你好呀!
在类的外面创建类的属性,实例:
1 class Dog: 2 def eat(self, food): 3 # print("小狗正在吃:", food) 4 print(self.color, '的', self.kinds, '正在吃', food) 5 6 dog1 = Dog() 7 dog1.kinds = '京巴' # 为dog1对象添加kinds属性,绑定为'京巴' 8 dog1.color = '白色' # dog1添加属性 为'白色' 9 dog1.color = '黄色' # 改变dog1的color属性10 print(dog1.color, "的", dog1.kinds) # 访问dog1 的属性,黄色 的 京巴11 12 dog2 = Dog()13 dog2.kinds = '哈士奇'14 dog2.color = '黑白相间'15 print(dog2.color, '的', dog2.kinds) # 黑白相间 的 哈士奇16 17 dog1.eat('骨头') #黄色 的 京巴 正在吃 骨头18 dog2.eat('窝头')# 黑白相间 的 哈士奇 正在吃 窝头
初始化方法
1、初始化方法会在构造函数创建实例后自动调用,且将实例自身通过第一参数self传入__init__方法
2、初始化方法如果需要return语句返回,则只能返回None
3、一般类都会倾向于将(实例)对象创建为有初始化状态的,
4、实例方法至少有一个形参,第一个形参代表调用这个方法的实例,一般命名为'self',因此类可能会定义一个名为__init__()的特殊方法(构造方法)
5、类定义了__init__()方法的话,类的实例化对象会自动调用__init__()方法
6、__init__有形参时,参数会通过__init__()传递到实例化对象上。
class complex: # 构造函数,在实例化时做一些类的初始化工作,__init__用来传参的 def __init__(self, name, age): # 定义类的方法 self.name = name # 实例变量(静态属性) self.age = agex = complex("作者",23) # 类的实例化,变成具体对象print(x.name,x.age)# 作者 23
类的方法与普通的函数只有一个特殊的区别————他们必须有一个额外的第一参数名称self,按照惯例它的名称是self,谁调用这个类的方法,self就指向谁。self代表类的实例化,而非类
class Test: #定义一个名为Test的类 def prt(self): #定义类的方法prt print(self) print(self.__class__) # self.__class__指向类t = Test() #类的实例化t.prt() #访问类的方法# <__main__.Test object at 0x000001836DFE10B8>#
self代表的是类的实例,代表当前对象的地址,而self.__class__则指向类Test。self不是python的关键词,我们把self换成其他的表示符也是可以的。
class Test: #定义一个名为Test的类 def prt(runoob): #定义类的方法prt print(runoob) print(runoob.__class__)t = Test() #类的实例化t.prt() #访问类的方法# <__main__.Test object at 0x000001836DFE10B8>#
类的方法
类的方法在类的内部,使用def关键词来定义一个方法,与一般函数定义不同,类方法必须包含参数self,且为第一个参数,self代表的是类的实例。
class people: #定义一个类 # 定义类的属性 name = '' age = 0 # 定义私有属性,私有属性在类外部无法直接进行访问 _weight = 0 # 定义构造的方法 def __init__(self,n,a,w): # 定义类的初始化属性 self.name = n self.age = a self._weight = w # 定义类的方法 def speak(self): print("%s说:我%d岁"%(self.name,self.age))# 实例化类 把一个类变成具体对象叫做类的实例化p = people("作者",18,30)p.speak()
# 作者说:我18岁
# 定义私有属性,私有属性在类外部无法直接进行访问 __weight = 0,在变量前面加双下划线
删除属性del语句
del 变量名 删除变量
del 列表[整数表达式] 删除列表中的元素
del 字典[键] 删除字典中的键
del 对象.属性 删除对象的属性
析构方法:
class 类名:
def __del__(self):
......
说明:析构方法在对象被销毁时做任何事情,因为销毁的时间难以确定
预置实例属性:
__dict__属性
__dict__属性绑定一个存储此实例自身变量的字典
1 class Dog:2 pass3 4 dog1 = Dog()5 print(dog1.__dict__) # {}6 dog1.kinds = '京巴'7 print(dog1.__dict__) # {'kinds': '京巴'}
__class__属性:
此属性用于绑定创建此实例的类
作用:可以借助于此属性来访问创建此实例的类
1 class Dog:2 pass3 dog1 = Dog()4 print(dog1.__class__) #5 dog2 = dog1.__class__()6 print(dog2.__class__)#
用于类的函数:
isinstance(obj, class_or_tuple) 返回这个对象obj是否是某个类的对象或某些类中的一个类的对象,如果是则返回True,否则返回False,type(obj) 返回对象的类型
继承
派生类
1 class DerivedClassName(BaseClassName1):23 .4 .5 .6
注意圆括号中积累的顺序,若是基类中有相同的方法名,而在子类使用时为指定,python从左向右搜索即方法在子类中未找到时,从左到右查找基类中时候包含方法。
BaseClassName(示例中的基类名)必须与派生类定义在一个作用域内。除了类,还可以用表达式,基类定义在另一个模块中时这一点非常有用:
class DerivedClassName(modname.BaseClassName):
单继承实例
1 # 类定义 2 class people: 3 # 定义类的属性 4 name = '' 5 age = 0 6 # 定义私有属性,私有属性在类外部无法直接访问 7 __weight = 0 8 # 定义构造方法 9 def __init__(self,n,a,w):10 self.name = n11 self.age = a12 self.__weight = w13 def speak(self):14 print("%s说:我%d岁"%(self.name,self.age))15 16 # 单继承类17 class student(people):18 grade = ''19 def __init__(self,n,a,w,g):20 # 调用父类的构造函数21 people.__init__(self,n,a,w)22 self.grade = g23 #覆写父类的方法24 def speak(self):25 print("%s 说: 我 %d 岁了,我在读 %d 年级"%(self.name,self.age,self.grade))26 27 s = student('凌贤鹏',10,60,3)28 s.speak()
凌贤鹏 说: 我 10 岁了,我在读 3 年级
多继承
1 class DerivedClassName(Base1, Base2, Base3):23 .4 .5 .6
需要注意圆括号中父类的顺序,若是父类中有相同的方法名,而在子类使用时未指定,python从左至右搜索 即方法在子类中未找到时,从左到右查找父类中是否包含方法。
1 #类定义 2 class people: 3 #定义基本属性 4 name = '' 5 age = 0 6 #定义私有属性,私有属性在类外部无法直接进行访问 7 __weight = 0 8 #定义构造方法 9 def __init__(self,n,a,w):10 self.name = n11 self.age = a12 self.__weight = w13 def speak(self):14 print("%s 说: 我 %d 岁。" %(self.name,self.age))15 16 #单继承示例17 class student(people):18 grade = ''19 def __init__(self,n,a,w,g):20 #调用父类的构函21 people.__init__(self,n,a,w)22 self.grade = g23 #覆写父类的方法24 def speak(self):25 print("%s 说: 我 %d 岁了,我在读 %d 年级"%(self.name,self.age,self.grade))26 27 # 另一个类,多重继承之前的准备28 class speaker():29 # 类的属性30 topic = ''31 name = ''32 def __init__(self,n,t):33 self.name = n34 self.topic = t35 def speak(self):36 print("我叫 %s,我是一个演说家,我演讲的主题是 %s"%(self.name,self.topic))37 38 #多重继承39 class sample(speaker,student):40 a = ''41 def __init__(self,n,a,w,g,t):42 # 调用父类的构函43 student.__init__(self,n,a,w,g)44 speaker.__init__(self,n,t)45 46 test = sample('凌贤鹏',18,23,4,'python')47 test.speak() #方法名重复了,默认调用的是括号中排前地父类的方法
我叫 凌贤鹏,我是一个演说家,我演讲的主题是 python
方法重写
如果你的父类方法的功能不能满足你的需求,你可以在子类重写你父类的方法
1 class parent: #定义父类 2 def mymethod(self): 3 print("调用父类的方法") 4 5 class child(parent): #定义子类 6 def mymethod(self): 7 print("调用子类方法") 8 9 c = child() #子类实例10 c.mymethod() #子类调用重写方法11 super(child,c).mymethod() #用子类对象调用父类已被覆盖的方法
调用子类方法调用父类的方法
super()函数是用于调用父类(超类)的方法
类属性与方法
类的私有属性
__private_attrs:两个写划线开头,声明该属性为私有类,不能在类地外部被使用或直接访问,在类内部的方法使用时self.private_attrs。
类的方法
在类地内部,使用def关键字来定义一个方法,与一般函数定义不同,类方法必须包含self,且为第一个参数,self代表的是类的实例。
self的名字并不是规定死的,也可以是其他的,但最好按照规定用self
类的私用方法
__private_method:两个下划线开头,声明该方法为私有方法,只能在类的内部调用 ,不能在类地外部调用。self.__private_methods。
1 class JustCounter: 2 __secretCount = 0 # 私有变量 3 publicCount = 0 # 公开变量 4 5 def count(self): 6 self.__secretCount += 1 7 self.publicCount += 1 8 print (self.__secretCount) 9 10 counter = JustCounter()11 counter.count()12 counter.count()13 print (counter.publicCount)14 print (counter.__secretCount) # 报错,实例不能访问私有变量
1 12 23 24 Traceback (most recent call last):5 File "test.py", line 16, in6 print (counter.__secretCount) # 报错,实例不能访问私有变量7 AttributeError: 'JustCounter' object has no attribute '__secretCount'
1 class Site: 2 def __init__(self, name, url): 3 self.name = name # public 4 self.__url = url # private 5 6 def who(self): 7 print('name : ', self.name) 8 print('url : ', self.__url) 9 10 def __foo(self): # 私有方法11 print('这是私有方法')12 13 def foo(self): # 公共方法14 print('这是公共方法')15 self.__foo()16 17 x = Site('菜鸟教程', 'www.runoob.com')18 x.who() # 正常输出19 x.foo() # 正常输出20 x.__foo() # 报错
类的专有方法
- __init__:构造函数,在生成对象时调用
- __del__ : 析构函数,释放对象时使用
- __repr__ : 打印,转换
- __setitem__ : 按照索引赋值
- __getitem__: 按照索引获取值
- __len__: 获得长度
- __cmp__: 比较运算
- __call__: 函数调用
- __add__: 加运算
- __sub__: 减运算
- __mul__: 乘运算
- __div__: 除运算
- __mod__: 求余运算
- __pow__: 乘方
运算符重载
1 class Vector: 2 def __init__(self, a, b): 3 self.a = a 4 self.b = b 5 6 def __str__(self): 7 return 'Vector (%d, %d)' % (self.a, self.b) 8 9 def __add__(self,other):10 return Vector(self.a + other.a, self.b + other.b)11 12 v1 = Vector(2,10)13 v2 = Vector(5,-2)14 print (v1 + v2)
Vector(7,8)