python-16-对象继承

面向对象的三大特征

  封装:根据职责将属性和方法封装到一个抽象的类中

  继承:实现代码的重用,相同的代码不需要重复编写

  多态:不同的对象调用相同的方法,产生不同的执行结果,增加代码的灵活度

一、单继承

  继承:子类拥有父类的方法和属性

  语法class 类名(父类):

         pass

     子类继承自父类,可以直接享受父类中已经封装好的方法,不需要再次开发

     子类中应该根据职责,封装子类特有的属性和方法

  继承的传递性:

    C类从B类继承,B类从A类继承

    那么C类就具有B类和A类的所有属性和方法

    子类拥有父类以及父类的父类 中封装的所有属性和方法

  方法的重写

    当父类封装的方法不能满足子类需求时,可以对方法进行重写(Override)

  重写有两种:

    1、覆盖父类方法(子类方法和父类完全不同)

      实现方式,在子类中定义一个和父类同名的方法并实现(只会调用子类方法,不会调用父类的方法)

    2、对父类方法进行扩展(子类的方法实现包含父类的方法实现)

      在子类中重写父类方法

      调用super.父类方法,来调用父类方法执行

      代码其他的位置针对子类的需求,缩写子类特有的代码实现

      

     另一种调用父类方法的方式:

      父类名.方法(self)不推荐,父类如果变了,方法调用的类名也要改

      

二、父类的私有属性和私有方法

  子类对象不能在自己的方法内部,直接访问父类的私有属性或私有方法;

  子类对象可以通过父类的公共方法间接访问到私有属性和私有方法。

  

class A:
    def __init__(self):
        self.num1 = 100
        self.__num2 = 200

    def __test(self):
        print("私有方法__test输出属性%d %d" % (self.num1, self.__num2))

    def test(self):
        print("访问私有属性%d" % self.__num2)
        self.__test()


class B(A):
    def demo(self):
        # 在子类对象方法中,不能访问父类的私有属性
        # print("访问父类的私有属性 %d" % self.__num2)
        # 也不能调用父类的私有方法
        # self.__test()
        print("父类公有属性%d" % self.num1)
        self.test()


# 创建子类对象
b = B()
print(b)
b.demo()
# 在外界不能直接访问对象的私有属性/调用对象的私有方法
# print(b.__num2)
# b.__test()

三、多继承

  子类可以拥有多个父类,并且具有所有父类的属性和方法

  语法:class 子类名(父类名1,父类名2,……):

         pass

 1 class A:
 2     def test(self):
 3         print("A的test方法")
 4 
 5 
 6 class B:
 7     def demo(self):
 8         print("B的Demo方法")
 9 
10 
11 class C(A, B):
12     pass
13 
14 
15 c = C()
16 c.demo()
17 c.test()

   注意:

    多个父类之间不要存在相同的属性或方法。

 1 class A:
 2     def test(self):
 3         print("A的test方法")
 4 
 5 
 6 class B:
 7     def test(self):
 8         print("B的test方法")
 9 
10 
11 class C(A, B):
12     pass
13 
14 
15 c = C()
16 c.test()  # A的test方法
 1 class A:
 2     def test(self):
 3         print("A的test方法")
 4 
 5 
 6 class B:
 7     def test(self):
 8         print("B的test方法")
 9 
10 
11 class C(B, A):
12     pass
13 
14 
15 c = C()
16 c.test()  # B的test方法

如果不同的父类之间存在同名的属性或方法,应尽量避免多继承。

四、Python中的MRO --方法搜索顺序

  python中针对类有一个提供了一个内置属性 __mro__ 可以查看方法的搜索顺序

  MRO是method resolution order ,主要用于多继承时判断方法、属性的调用路径

 1 class A:
 2     def test(self):
 3         print("A的test方法")
 4 
 5 
 6 class B:
 7     def test(self):
 8         print("B的test方法")
 9 
10 
11 class C(B, A):
12     pass
13 
14 
15 c = C()
16 # 确定C类对象调用的顺序
17 print(C.__mro__)
18 c.test()

(<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
B的test方法

 1 class A:
 2     def test(self):
 3         print("A的test方法")
 4 
 5 
 6 class B:
 7     def test(self):
 8         print("B的test方法")
 9 
10 
11 class C(A, B):
12     pass
13 
14 
15 c = C()
16 # 确定C类对象调用的顺序
17 print(C.__mro__)
18 c.test()

(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
A的test方法

五、新式类和旧式(经典)类

  objec是python为所有对象提供的基类,提供有一些内置属性和方法,可以使用dir函数查看

  新式类:以object为基类的类,推荐使用

  经典类:不以object为基类的类,不推荐使用

  

  新式类和经典类,在多继承时 ,会影响到方法的搜索顺序

  为了保证编写的代码同时在python2.X和python3.X运行

  今后在定义类时,如果没有父类,建议统一继承自object:

    class 类名(object):

      pass

在python2.x中

 

猜你喜欢

转载自www.cnblogs.com/onroad2019/p/12187903.html