欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

第15讲 python面向对象-继承、多态

程序员文章站 2022-05-28 14:24:50
...

1、继承的简介
1)提高了代码的复用性
2)让类与类之间产生了关系,有了这个关系,才有了多态的特性
3)继承也是面向对象的三大特性之一

定义一个动物类
如何能让这个当前的动物类实现全部的功能
1)直接修改动物类,在这个类中添加我们需要的功能
2)可以直接创建一个新类
3)直接从动物类继承

在创建类的时候,如果我们省略弗雷则默认父类为object
所有类都继承object,object是所有类的父类
class Animal:
def run(self):
print(‘动物在跑’)

def sleep(self):
    print('动物在睡觉')

class Cat:
def run(self):
print(‘猫在跑’)

def sleep(self):
print(‘猫在睡觉’)

class Cat(Animal):
def speak(self):
print(‘喵喵喵’)
pass

c = Cat()
print©
c.run()
c.sleep()
c.speak()
返回值
<main.Cat object at 0x0000022CEBD59A90>
动物在跑
动物在睡觉
喵喵喵

检查实例
r1 = isinstance(c,Cat)
r2 = isinstance(c,Animal)
print(r1,r2)
返回值:True True

#issubclass(),子类检查
class Person():
pass
print(issubclass(Person,object))
print(‘issubclass=’,issubclass(Cat,Animal))
#返回值:
True
issubclass= TrueTrue True

2、重写
如果子类中有父类同名额方法,则通过子类的实例去调用该方法时,会调用子类的方法而不是父类的方法,这个特点也称之为我们所说的方法的重写(覆盖)
class Animal:
def run(self):
print(‘动物在跑’)

def sleep(self):
print(‘动物在睡觉’)

class Cat(Animal):
先找自己,没有再找父类
def run(self):
print(‘猫在跑’)

def speak(self):
print(‘喵喵喵’)
pass

a = Animal()
a.run()
返回值:动物在跑
c = Cat()
print©
c.run()
返回值:猫在跑

当我们调用一个对象的方法时,会优先去当前对象中去寻找是否有该方法,如果有则直接调用
如果没有,则去当前对象的父类中寻找,如果父类中有则直接调用
如果没有,则去父类对象的父类中去寻找,依次类推,直到找到object,如果没有则报错
class A(object):
def text(self):
print(‘AAA’)

class B(A):
def text(self):
print(‘BBB’)

class C(B):
def text(self):
print(‘CCC’)

c = C()
c.text()
返回值:CCC

3、super()
class Animal:
def init(self,name):
self._name = name

@property
def name(self):
return self._name

@name.setter
def name(self,name):
self._name = name

父类中的所有方法都会被子类中继承,包括特殊方法
class Cat(Animal):

我希望可以直接调用父类中的__init__方法来初始化父类中的属性
super()可以获得当前类的父类
通过super()返回对象调用父类方法时,不要传递self
def init(self,name,age):
super().init(name)
self._name = name
self._age = age

def run(self):
print(‘猫在跑’)

def speak(self):
print(‘喵喵喵’)

@property
def age(self):
return self._age

@age.setter
def age(self,age):
self._age = age

c = Cat(‘小白’,5)
c.name = ‘加菲猫’
c.age = 8
print(c.name)
print(c.age)
返回值:
加菲猫
8

4、多重继承
bases
语法 类名.bases 这个方法可以获得当前类所有类的父类
python 支持多重继承,也就是我们可以为一个类同时制定多个父类
我们在开发的时候,尽量不用多重继承,原因是增加了代码的复杂程度
如果多个父类中出现重名的方法,则会先在第一个父类中寻找,然后在找第二个,然后再找第三个
而且后面覆盖前面

class A(object):
#def text(self):

print(‘AAA’)

pass

class B(object):
def text(self):
print(‘B中text方法’)
def text2(self):
print(‘BBB’)

class C(A,B):
pass

print(B.bases)
返回值:(<class ‘object’>,)

c = C()
c.text()
返回值:B中text方法

5、多态
多态也是面向对象的三大特性之一
一个对象可以以不同的形态去呈现

鸭子类型
如果有一个东西,走路象鸭子,叫声象鸭子,它就是鸭子
多态使得我们编程更有灵活性

class A:

def init(self,name):
self._name = name

@property
def name(self):
return self._name

@name.setter
def name(self,name):
self._name = name

class B:
def init(self,name):
self._name = name

@property
def name(self):
return self._name

@name.setter
def name(self,name):
self._name = name

class C:
pass

a = A(‘葫芦娃’)
b = B(‘钢铁侠’)
c = C()

def say(obj):
print(‘您好%s’%obj.name)

say(a)
#返回值:您好葫芦娃
say(b)
#返回值:您好钢铁侠
say©
#say©报错,‘C’ object has no attribute ‘name’

def say2(obj):
#做类型检查
#违反了多态的函数只适用于一种类型的对象,无法处理其它类型的对象,这样会导致函数的实用性非常差
if isinstance(obj,A):
print(‘您好%s’%obj.name)

say2(a)
#返回值:您好葫芦娃

len()
之所以一个对象能够通过len()函数获取长度,是因为对象中具有一个特殊方法__len__
lst = [1,2,3]
s = ‘python’
print(len(lst))
print(len(s))
print(len(b))
#返回值:10

总结:
面向对象的三大特征 封装、继承、多态
封装 确保对象中数据的安全
继承 保证了对象的可扩展性
多态 保证了程序的灵活性

6、属性和方法
class A(object):
#类属性 直接在类中定义的属性
#类属性 可以通过类本身的实例访问
#类属性 只能通过类对象来修改,无法通过实例对象来修改
count = 0

#实例属性通过实例对象添加的属性叫实例属性
#实例属性 只能通过实例对象来访问和修改,但类对象无法访问和修改
def init(self):
self.name = ‘葫芦娃’

#实例方法
#在类中定义,以self为参数的方法都是实例方法
#实例方法在调用时,Python会将调用的对象作为self传入
#当通过类调用时,不会自动传入self
def text(self):
print(‘这是text方法’,self)

#类方法
#在类的内部使用 @classmethod 来装饰的方法叫做类方法
#类方法的第一个参数是cls 会被自动传递 cls是当前的类对象
@classmethod
def text2(cls):
print(‘这是text2方法’,cls)
print(cls.count)

#静态方法
#在类中内部使用@staticmethod 来修饰的方法属于静态方法
#静态方法不需要指定在任何默认的参数,静态方法可以通过类和实例调用
#静态方法可以理解为保存到类中的一个函数
@staticmethod
def text3():
print(‘text3执行了’)

a = A()
a.count = 5
print(‘A’,A.count)
print(‘a’,a.count)
#返回值:0 5
A.count = 5
print(‘A’,A.name)
#报错:AttributeError: type object ‘A’ has no attribute ‘name’
print(‘a’,a.count)
#返回值:5 5
print(‘a’,a.count)
print(‘a’,a.name)
a.text()
#返回值:这是text方法 <main.A object at 0x0000018E47B8B1D0>
A.text()
#报错:TypeError: text() missing 1 required positional argument: ‘self’
A.text(a)
#返回值:这是text方法 <main.A object at 0x0000018E47B8B1D0>

a.text3()
#返回值:text3执行了
A.text3()
#返回值:text3执行了