Python笔记_第三篇_面向对象_6.继承(单继承和多继承)

1. 概念解释

  继承:有两个类:A类和B类。那么A类就拥有了B类中的属性和方法。

  * 例如:Object:是所有类的父亲,还可以成为基类或者超类(super())

  * 继承者为子类,被继承者成为父类。

2. 继承的作用

  * 继承花间了代码,减少了冗余。

  * 提高了代码的健壮性。

  * 提高了代码的安全性。

  * 是多态的前提。(Polymorphism)

  继承也有缺点:继承是高内聚、高耦合的形态。

  (备注:耦合和内聚是描述类与类之间的关系。耦合性越低、内聚性越高,代码质量越好)

3. 单继承

  超类函数:super()

  格式1:

  super(当前类名,self).继承内容

  其意思是:调用父类中的内容。

  格式2:

  super().继承内容 # 也可以不写括号中的内容。

  

  举例说明1:一个单继承的小例子

class Person(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def run(self):
        print("run")
    def eat(self,food):
        print("eat" + food)


class Student(Person):
    def __init__(self,name,age):
        # 调用父类中的__init__也就是Person中的
        super(Student,self).__init__(name,age)

stu = Student("Tom",18)
print(stu.name,stu.age)
stu.run() # 调用父类中的方法。

  举例说明2:我们发现子类其实也可以有自己的一些属性。

子类中还可以有自己独有的属性
class Person(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def run(self):
        print("run")
    def eat(self,food):
        print("eat" + food)


class Student(Person):
    def __init__(self,name,age,stuID):
        # 调用父类中的__init__也就是Person中的
        super(Student,self).__init__(name,age)
        # 子类可以有一些独有的属性
        self.stuID = stuID

stu = Student("Tom",18,100)
print(stu.name,stu.age)
print(stu.stuID)

   

  举例说明3:

  另外,我们前面说过单下划线和双下划线中"__变量名"的这种形式,属于私有属性。这样子类继承父类的时候私有属性的时候我们可以通过子类访问父类中获取私有属性的方法得到。这里我们写了一个setMoney和getMoney的方法。可以访问到父类当中的私有属性了。

  我们还发现super()超类的方法,还可以直接用父类的名字点上想继承的属性,其效果也是一样的。

# 父类如果有私有属性无法继承过来。
# 但是通过子类访问父类当中获取私有属性的方法可以得到私有属性
class Person(object):
    def __init__(self,name,age,money):
        self.name = name
        self.age = age
        self.__money = money # 私有属性
    # 写set和get方法
    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)

class Student(Person):
    def __init__(self,name,age,money,stuID):
        # 调用父类中的__init__也就是Person中的
        super(Student,self).__init__(name,age,money)
        # 表示让父类中的self代表当前的Student的对象

        # Person.__init__(self,name,age,money) #这种写法也是可以的
        # 此时的self相当于创建子类的对象

        # super().__init__(name, age, money) # 其实里面的内容不写也可以

        # 子类可以有一些独有的属性
        self.stuID = stuID

    def stuFunc(self):
        print(self.__money)

stu = Student("Tom",18,123456,110)
print(stu.name,stu.age)
# stu.stuFunc()
# 报错
# Traceback (most recent call last):
#   File "F:/QUANT/练习/day04.py", line 95, in <module>
#     stu.stuFunc()
#   File "F:/QUANT/练习/day04.py", line 90, in stuFunc
#     print(self.__money)
# AttributeError: 'Student' object has no attribute '_Student__money'

print(stu.getMoney()) # 通过继承过来的的共有方法访问私有属性。

4. 多继承

  也就是说,我们不光一个子类可以继承一个父类,也可以继承多个父类,通过逗号进行分割。  

  举例说明4:一个简单的多继承。

class Father(object):
    def __init__(self,money):
        self.money = money

    def play(self):
        print("play")
    def func(self):
        print("func")

class Mother(object):
    def __init__(self, faceValue):
        self.faceValue = faceValue

    def eat(self):
        print("eat")

    def func(self):
        print("func2")

class Child(Father,Mother):
    def __init__(self,money,faceValue):
        Father.__init__(self,money)
        Mother.__init__(self,faceValue)
        # 此时的self指的是当前类的self


# 我们写一个主程序
def main():
    c = Child(300,100)
    print(c.money,c.faceValue)
    c.play()
    c.eat()
    # 注意如果方法名相同,默认调用的是在括号中排前面的父类中的方法
    c.func()

if __name__ == '__main__':
    main()

  

  举例说明5:

  思考:在添加100种动物,都有name属性和eat方法。采用继承解决的方式
  定义一个有name属性和eat方法的Animal类,让所有的动物类都继承自Animal

思考:在添加100种动物,都有name属性和eat方法。采用继承解决的方式
定义一个有name属性和eat方法的Animal类,让所有的动物类都继承自Animal

class Animal(object):  # 动物类
    def __init__(self,name):
        self.name = name

    def eat(self):
        print(self.name + "")


class Cat(Animal):  # 猫类
    def __init__(self,name):
        super(Cat,self).__init__(name)
    # 不用写了
    # def eat(self):
    #     print(self.name + "")


class Mouse(Animal): # 老鼠类
    def __init__(self, name):
        super(Mouse, self).__init__(name)
    # 不用写了
    # def eat(self):
    #     print(self.name + "")


Tom = Cat("Tom")
Jerry = Mouse("Jerry")

Tom.eat()
Jerry.eat()