一 python自动化基础能力:3.python基础上之数据类型,函数(21)


多态字面理解即多种形态,在面向对象中指一个对象可以以不同的形态呈现 。
class A(object):def __init__(self,name):self._name = name@propertydef name(self):return self._name@name.setterdef name(self,name):self._name = nameclass B(object):def __init__(self, name):self._name = name@propertydef name(self):return self._name@name.setterdef name(self, name):self._name = namedef speak(obj):print('Hello,%s' % obj.name)a = A('Tom')b = B('Jerry')speak(a)speak(b)
打印
Hello,TomHello,Jerry
定义一个新类C,但是没有name属性时,
class A(object):def __init__(self,name):self._name = name@propertydef name(self):return self._name@name.setterdef name(self,name):self._name = nameclass B(object):def __init__(self, name):self._name = name@propertydef name(self):return self._name@name.setterdef name(self, name):self._name = nameclass C(object):passdef speak(obj):print('Hello,%s' % obj.name)a = A('Tom')b = B('Jerry')c= C()speak(a)speak(b)speak(c)
会抛出异常,: 'C'has no'name',
增加类型检查,
class A(object):def __init__(self,name):self._name = name@propertydef name(self):return self._name@name.setterdef name(self,name):self._name = nameclass B(object):def __init__(self, name):self._name = name@propertydef name(self):return self._name@name.setterdef name(self, name):self._name = nameclass C(object):passdef speak(obj):print('Hello,%s' % obj.name)def test_speak(obj):'''类型检查'''if isinstance(obj,A):print('Hello,%s' % obj.name)a = A('Tom')b = B('Jerry')c= C()test_speak(a)test_speak(b)test_speak(c)
打印Hello,Tom 。
在()这个函数中做了类型检查,也就是obj是A类型的对象的时候,才可以正常执行,其他类型的对象无法使用该函数 。
这个函数其实就是违反了多态 。
违反了多态的函数,只适合于一种类型的对象,无法适用于其他类型的对象,导致函数的适用性非常差 。
多态使面向对象的编程更加具有灵活性 。
l = [1,2,3]s = 'python'print(len(l),len(s))
如上,len()函数既可以得到list的长度,又可以获取str的长度,
len()就可以检查不同对象类型的长度就是面向对象的特征之一——多态 。
len()的底层实现:
之所以len()函数能获取长度,是因为这些对象中有一个特殊方法()方法;
换句话说,只要对象中有()方法,就可以通过len()方法来获取对象的长度 。
class B(object):def __init__(self, name):self._name = name@propertydef name(self):return self._name@name.setterdef name(self, name):self._name = nameb = B('Jerry')print(len(b))
会报错:of type 'B' has no len() 。
在B中加入()方法后,
class B(object):def __init__(self, name):self._name = name@propertydef name(self):return self._name@name.setterdef name(self, name):self._name = namedef __len__(self):return 1b = B('Jerry')print(len(b))
会打印1
面向对象的三大特征:
1.封装:确保对象中的数据更安全;
2.继承:保证对象的可扩展性;
3.多态:保证了程序的灵活性 。
12.类中的属性和方法
类属性是直接在类中定义的属性,类属性可以通过类或类的实例访问;
通过实例对象添加的属性属于实例属性 。
class A(object):#类属性count = 0a = A()print(A.count)print(a.count)