面向对象术语
类(Class):用来描述具有相同属性和方法的对象集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
类属性(类变量):类属性在整个实例化的对象中是公用的。类属性定义在类中且在函数体之外。类变量通常不作为实例变量使用。
数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据。
方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
实例变量:定义在方法中的变量,只作用于当前实例的类。
继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系。
实例化:创建一个类的实例,类的具体对象。
方法:类中定义的函数。
对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。
类定义
Python中的类提供了面向对象编程的所有基本功能:类的继承机制允许多个基类,派生类可以覆盖基类中的任何方法,方法中可以调用基类中的同名方法。
对象可以包含任意数量和类型的数据。
举个栗子:
class test(object): #定义一个类,在3.5中必须指定基类object
i = 123 #类变量
def func(self): #类方法
print('第一个类')
return 'hello python'
s = test() #通过类实例化对象
str = s.func() #对象调用类方法
print(test.i) #通过类名调用类变量
print(str) #类返回值
#output
第一个类
hello python
类有一个名为 init() 的特殊方法(构造方法),该方法在类实例化时会自动调用, init() 方法可以有参数,参数通过 init() 传递到类的实例化操作上。
类实例化后,可以使用其属性,实际上,创建一个类之后,可以通过类名访问其属性和方法;实例化类后可以使用其属性,也可以动态的为实例对象添加属性而不影响类对象。可以使用点(.)来访问对象的属性,也可以使用函数的方式来访问属性:
举个栗子:
class A(object):
def __init__(self,x):
self.x = x
def static_func(y=5):
print(y)
d = A(10) #类实例化对象
print(getattr(d,'x')) #getattr访问对象的属性,返回结果:10
print(hasattr(d,'x')) #hasattr检查对象属性是否存在,返回结果:True
print(setattr(d,'y','zhang')) #设置对象的属性,如果属性不存在则创建新属性,返回结果:None
print(d.y) #打印实例对象属性值,返回结果:zhang
delattr(d,'y') #defattr删除对象属性
print(hasattr(d,'x')) #返回结果:True
python3类的专有方法:
init 构造函数,在生成对象时调用
del 析构函数,释放对象时使用
repr 打印,转换
setitem按照索引赋值
getitem按照索引获取值
len获得长度
cmp比较运算
call函数调用
add加运算
sub减运算
mul乘运算
div除运算
mod求余运算
pow乘方
举个栗子:
class test1(object):
a = 3
b = 2
def get(self):
print('取幂:',self.b.__pow__(self.a))
print('求余数:',self.b.__mod__(self.a))
print('乘:',self.b.__mul__(self.a))
print('减:',self.b.__sub__(self.a))
print('加:',self.b.__add__(self.a))
print('输出:',self.b.__repr__())
d = test1()
d.get()
输出结果
取幂: 8
求余数: 2
乘: 6
减: -1
加: 5
输出:2
python3类属性、类方法:在类的内部,使用 def 关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数 self, 且为第一个参数,self 代表的是类的实例。
举个栗子:
class people:
#定义基本属性
name = ''
age = 0
#定义构造方法
def __init__(self,n,a):
self.name = n
self.age = a
def speak(self):
print("%s 说: 我 %d 岁。" %(self.name,self.age))
# 实例化类
p = people('xiaoming',10)
p.speak()
python3静态方法:静态方法是一种普通函数,就位于类定义的命名空间中,使用装饰器@staticmethod定义静态方法。类对象和实例都可以调用静态方法,静态方法不能调用类属性和实例属性,但可以调用传参。
举个栗子:
class A(object):
number = 10
def __init__(self,name):
self.name = name
def car(self):
print(self.name)
@staticmethod #定义静态方法
def cat(x,y): #定义调用传参
print('静态方法:%s'%(x*y))
d = A('hello') #实例化类
d.car() #实例方法,返回结果:hello
d.cat(5,4) #实例调用静态方法,返回结果:静态方法:20
A.cat(6,3) #类调用静态方法,返回结果:静态方法:18
类的封装
封装,也就是把客观事物封装成抽象的类,并且类可以使得自己的数据和方法,只让可信的类或者对象操作,对不可信的进行信息隐藏。python通过变量名命名来区分属性和方法的访问权限。
类的私有属性: __private_attrs:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时self.__private_attrs。
类的私有方法:__private_method:两个下划线开头,声明该方法为私有方法,不能在类外部调用。在类的内部调用 self.__private_methods
举个栗子:
class father(object):
__name = '私有属性'
age = "公有属性"
def func(self):
print(self.age)
print(self.__name)
def __foo(self): #定义私有方法
print(self.__name)
class son(father):
def show(self):
print(father.age) #返回结果:公有属性
obj1 = father()
obj1.func() #返回结果:公有属性 私有属性
#obj1.__foo() #直接调用会报错,只有通过"_类名__方法"的形式调用
obj1._father__foo() #调用私有方法,返回结果:私有属性
print(obj1.age) #返回结果:公有属性
#print(obj1.__name) #直接调用会报错,通过“_类名__属性”方法调用
print(obj1._fater__name) #调用私有属性,返回结果:私有属性
obj2 = son()
obj2.show() #调用父类属性,返回结果:公有属性
obj2.func() #返回结果:公有属性
obj2.__foo() #调用父类方法错误
obj2._father__foo() #正确调用父类方法,返回结果:私有属性
继承
继承是面向对象的重要特征之一,继承是两个类或者多个类之间的父子关系,子类可继承父类的所有公有实例变量和方法。继承实现了代码的重用,减少代码的重新编写。
python在类名后用一对圆括号表示继承关系,括号中的类表示父类或基类
经典类和新式类:
#经典类和新式类的区别:当前类或者父类继承了object类,那么该类便是新式类,否则便是经典类。
class old: #经典类写法
pass
class new(object): #新式类写法
pass
在python中类继承的特点:
1:在继承中,基类的构造(init())方法不会被自动调用,它需要在其派生类的构造中专门调用。使用super().init()或parentClassName.init()
2:在调用基类的方法时,需要加上基类的类名前缀,且需要带上self参数变量。区别于在类中调用普通函数时并不需要带上self参数
3:Python总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找调用的方法,找不到才去基类中找)。
如果在继承元组中列了一个以上的类,那么它就被称作"多重继承" 。
举个栗子:
class test(object): #定义父类
def __init__(self,name,age):
self.name = name
self.age = age
def buygo(self):
print('%s[%s]岁' %(self.name,self.age))
class test_student(test): #调用父类
def __init__(self,name,age,good):
test.__init__(self,name,age) #重写父类构造方法
self.good = good
def buygo(self): #如果父类中的方法名相同于子类中的方法名,子类方法将覆盖父类方法。
print('%s[%s]岁,很%s' %(self.name,self.age,self.good))
#通过类实例化对象
zhangsan = test_student('zhangsan','厉害')
lisi = test_student('lisi',22,'能长个子吧')
zhangsan.buygo() #返回结果:zhangsan[20]岁,很厉害
lisi.buygo() #返回结果:lisi[22]岁,很能长个子吧
多态
多态依赖于继承,多态的作用,就是为了类在继承和派生的时候,保证继承类中实例的某个属性或方法的调用,实现接口的重用。
举个栗子:
class A(object):
def __init__(self):
self.name = 'ZHANGSAN'
def show(self):
print('A.show:',self.name)
class B(A):
def show(self):
print('show_b:',self.name)
class C(A):
def show(self):
print('show_c:',self.name)
def func(obj): #定义函数,传递对象
obj.show() #通过类实例对象调用类下的方法
A_obj = A()
B_obj = B()
C_obj = C()
func(A_obj)
func(B_obj)
func(C_obj)
运行结果:
A.show: ZHANGSAN
show_b: ZHANGSAN
show_c: ZHANGSAN
网友评论