python面向对象编程.下篇

继承与多态

继承

当定义一个class的时候,可以从某个现有的class继承,新的class称为 子类(Subclass),而被继承的class称为 基类、父类或超类(Base class、Super class)

举个例子:

class animal(object):
	def run(self):
		print('animal is running')
class dog(animal):
	pass
class cat(animal):
	pass

上例中animaldogcat父类

而继承就可以使得 子类 获得了 父类 的全部功能。因此:

d = dog()
print(d.run()) 
# result is 'animal is running'

当然,也可以对子类增加一些方法,而当子类和父类都存在相同的run()方法时,我们说,子类的run()覆盖了父类的run(),在代码运行的时候,总是会调用子类的run()

多态

比如上个例子中的变量dd既是dog的实例,又是animal的实例

多态有个著名的 开闭原则

  • 对扩展开放 :允许新增新的子类
  • 对修改封闭 :不需要修改依赖父类的某一个函数,子类可直接调用

获取对象信息

使用type():

基本类型和指向变量的函数或者类都可以使用type()来判断

>>> type(123)
<class 'int'>
>>> type('str')
<class 'str'>
>>> type(None)
<type(None) 'NoneType'>

>>> type(abs)
<class 'builtin_function_or_method'>
>>> type(a)
<class '__main__.Animal'>
使用isinstance()

但是要判断一个有继承关系的class怎么办?,这时候就要使用isinstance()

class Husky(dog)
h = Husky()
print(isinstance(h, Husky))
# result is True
print(isinstance(h, dog)
# result is True

isinstance()还可以判断一个变量是否是某些类型中的一种,比如下面的代码就可以判断是否是list或者tuple:

>>> isinstance([1, 2, 3], (list, tuple))
True
>>> isinstance((1, 2, 3), (list, tuple))
True
使用dir()

如果要获得一个对象的所有属性和方法,可以使用dir()函数,它返回一个包含字符串的list,比如,获得一个str对象的所有属性和方法:

>>> dir('ABC')
['__add__', '__class__',..., '__subclasshook__', 'capitalize', 'casefold',..., 'zfill']

类似__xxx__的属性和方法在Python中都是有特殊用途的,比如__len__方法返回长度。在Python中,如果你调用len()函数试图获取一个对象的长度,实际上,在len()函数内部,它自动去调用该对象的__len__()方法,所以,下面的代码是等价的:

print(len('ABC'))
print('ABC'.__len__())
# boths' results are '3' 

同理,如果我们自己写的类想要使用len()函数的话,我们就可以自己写一个__len__()的方法:

class MD(object):
	def __len__(self):
		return 11
d=MD()
print (len(d))
#result is 11
getattr()setattr()以及hasattr()
class Mo(object):
	def __init__(self):#赋予类属性的def
		self.x=9
a=Mo()

print(hasattr(obj, 'x')) #有属性'x'吗?
# result is ture
print(hasattr(obj, 'y')) #有属性'y'吗?
# result is flase
setattr(obj, 'y', 19) #设置一个属性'y'
print(hasattr(obj, 'y')) #有属性'y'吗?
# result is ture
getattr(obj,'y',404) # 获取属性'y',如果不存在,返回默认值404
# result is 19
getattr(obj,'z',404) # 获取属性'z',如果不存在,返回默认值404
# result is 404
类属性

给实例绑定属性的方法是通过实例变量,或者通过self变量

>>> class Student(object):
...     name = 'Student'
...
>>> s = Student() # 创建实例s
>>> print(s.name) # 打印name属性,因为实例并没有name属性,所以会继续查找class的name属性
Student
>>> print(Student.name) # 打印类的name属性
Student
>>> s.name = 'Michael' # 给实例绑定name属性
>>> print(s.name) # 由于实例属性优先级比类属性高,因此,它会屏蔽掉类的name属性
Michael
>>> print(Student.name) # 但是类属性并未消失,用Student.name仍然可以访问
Student
>>> del s.name # 如果删除实例的name属性
>>> print(s.name) # 再次调用s.name,由于实例的name属性没有找到,类的name属性就显示出来了
Student

从上面的例子可以看出,在编写程序的时候,千万不要对实例属性和类属性使用相同的名字,因为相同名称的实例属性将屏蔽掉类属性,但是当你删除实例属性后,再使用相同的名称,访问到的将是类属性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值