Python基础之继承和多态

继承
单继承

简单来说,一个子类只能有一个父类,被称为单继承

注意:在使用继承时,尽量一个类存在于一个模块中

比如,我们定义了一个Animal的class,有一个run()方法

class Animal(object)def run(self):
        print("Animal is running....")

当我们需要编写Dog和Cat类时,就可以直接从Animal类继承:

class Dog(Animal):
    pass

class Cat(Animal):
    pass

对于Dog来说,Animal就是它的父类,对于Animal来说,Dog就是它的子类,Cat和Dog类似。

继承有什么好处?最大的好处就是子类获得了父类的全部功能,由于Animal实现了run()方法,因此,Dog和Cat作为它的子类,什么事也没干,就自动拥有了run()的方法。

dog = Dog()
dog.run()

cat = Cat()
cat.run()

当然,也可以对子类增加一些方法,比如Dog类:

class Dog(Animal):    
    def eat(self):
        print("Eating meat....")
#以前的写法 class Person(object):
#但是实质上,如果没有显示的写出父类,则这个类的父类默认为object
#object是所有类的父类或者超类
class Person(object):
    #构造方法
    def __init__(self, name, age, money):
        self.name = name
        self.age = age
        self.__money = money
        
     #get/set方法
    def setMoney(self, money):
        self.__money = money
        
    def getMoney(self):
        return self.__money
    
    def run(self):
        print("run")
        
    def eat(self, food):
        print("eat", food)
        
from person  import Person
class Student(Person):
    def __init__(self, name, age, money, stuId):
        #调用父类中的构造方法
        #方法1 super(当前类,self).__init__(参数列表)
        #super(Student,self).__init__(name, age, money, stuId)
        #方法2 父类名.__init__(属性列表)
        Person.__init__(self, name, age, money)
        #子类可以有一些自己独有的属性
        self.stuId = stuId
    def setFunc(self):
        print(self.__money)
from person import Person

class Worker(Person):
    def __init__(self, name, age, money)
    	super(Worker,self).__init__(name, age, money)
    # 在子类中定义和一个父类中重名的函数
    def run(self):
        print("子类中的run方法被调用了")

总结:

继承的特点:

a. 子类对象可以直接访问父类中未私有的对象

b. 子类对象可以调用父类中的方法

c. 父类对象不能访问子类中特有的属性或者方法

优缺点:

优点:

1.可以简化代码,减少冗余

2.提高代码的维护性

3.提高了代码的安全性

缺点:

耦合和内聚被用来描述类与类之间的关系,耦合性越低,内聚性越高,说明代码越好,

但是,在继承关系中,耦合性相对比较高,如果修改父类,子类也会随着变化

多继承

顾名思义:就是一个子类中可以有多个父类,比如一个孩子有一个爸爸一个妈妈

from  child import Child

def main():
    c = Child(300, 100)
    print(c.money, c.faceValue)
    c.play()
    c.eat()
    #注意:如果多个父类中的方法名相同,默认调用的是子类括号中排前面的父类中的方法
    #此时调用的是Father中func方法
if __name__ == "__mian__":
    main()
class Father(object):
    def __init__(self, money):
        self.money = money
    def play(self):
        print("play")
    def func(self):
        print("Father")
class Mother(object):
    def __init__(self, faceValue):
        self.faceValue = faceValue
    def eat(self):
        print("eat")
    def  func(self):
        print("Mother")     
from father import Father
from mother import Mother

class Child(Father, Mother):
    def __init__(self, money, faceValue):
        #注意:分别调用各个父类中的构造方法
        Father.__init__(self, money)
        Mother.__init__(self, faceValue)
        #子类中同样可以有自己独有的特性
  

总结:

  1. 子类可以从多个父类中继承属性和方法
  2. 一个父类可以有多个子类
  3. 一个子类可以有多个父类
多态

多态是指一类事物的有多种状态【一个抽象类有很多子类,因而多态的概念依赖于继承。】

1.序列有多种形态:字符串,列表,元组

2.动物有多中形态:猫,狗

定义父类:

class Animal(object)def run(self):
        print("Animal is running....")

定义子类:

class Dog(Animal):
    def run(self):
        print("Dog is running...")
    
    def eat(self):
        print("Eating meat....")

继承的第二个好处是,我们可以在自己需要的时候,对我们的代码进行改进。当子类与父类都存在相同的run()方法的时候,子类中的run()覆盖了父类中的run(),在代码运行的时候,总会调用子类中的run().

这时候我们就获取了继承的另外一个好处:多态。

若要理解多态,我们首先要对数据类型再进行说明,我们定义一个class的时候,其实就是定义了一种数据类型。

a = list() #a是list类型
b = Animal() #b是Animal类型
c = Dog() #c是Dog类型

判断一个变量是否是某个类型们可以使用instance()来判断

>>>isinstance(a,list)
True
>>>isinstance(b,Animal)
True
>>>isinstance(c,Dog)
True
#c不仅是Dog还是Animal
>>>isinstance(c,Animal)
True

在继承的关系中,如果一个实例的数据类型是某个子类,那么它的数据类型也可以被看做是父类。

多态的优点:

class Animal(object)#def run(self):
     #   print("Animal is running....")
     
    @staticmethod
    def run2(Animal):
        Animal.run()
        
class Dog(Animal):

    def run(self):
        print('Dog is running...')

class Cat(Animal):

    def run(self):
        print('Cat is running...')

Animal.run2(Dog())
Animal.run2(Cat())
#结果
Dog is running...
Cat is running...

新增子类的时候我们不需要对我们的run2()做任何的修改,任何依赖Animal作为参数的函数都可以不加修饰的正常的运行。

多态的优点就是,当我们需要传入Dog,Cat,…时我们只需要接收Animal类型的即可,因此,传入的类型只要是Animal类或者是子类,就会自动调用实际类型的run()方法,这就是多态的意思。

获取对象属性

使用type()来判断对象类型

>>>type(123)

若是一个变量指向函数或者是类,依然可以使用type()判断。

isinstance()可以判断一个对象是否属于某种类型

>>> a = Animal()
>>> b = Dog
>>> isinstance(a,Animal)
True
>>> isinstance(b,Animal)
True

还可以判断一个变量是否是某些类型中的一种,比如下面的代码:

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

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

>>> dir(a)
函数重写
'''
重写:将函数重写一遍
__str__():在调用print打印对象时自动调用,是给用户用的,是一个描述对象的方法.
__repr__():是给机器用的,在python解释器里面直接敲对象名在回车后调用方法
注意:在没有str时,且有repr,__str__=__repr__
'''
class Animal(object):
    def __init__(self, name, age, height, weight):
        self.name = name
        self.age = age
        self.height = height
        self.weight = weight
     def __str__(self):
        return "%s-%d-%d-%d"%(self.name, self.age, self.height, self.weight)
ani  = Animal("大黄", 5, 60, 25)
#print(per.name, per.age, per.height, per.weight)
#在打印ani时自动调用str函数
print(ani)

#优点或者使用时机:当一个对象的属性值很多,并且都需要打印,重写__str__方法后,简化了代码,方便查看.

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值