python之继承

继承是所有开发语言的必修内容,而本文写的只是Python继承中的特殊之处,关于继承概念及内容可以自行百度(不装B,感觉百度挺好的)

        1.构造函数:

            要说继承,先要说一下构造函数。Java要求是与类名相同并且无返回值,而Python则是强制要求命名为“__init__()”。

            当创建类的对象时,会自动先调用构造函数,一般用于初始化。构造函数可以不写,那么程序会隐式自动增加一个空的构造函数。

       

        2.继承写法:

           (1).class 空格 类名称 括号内填写父类名 冒号

            具体写法如下

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

class A:

 

    def __init__(self):

        pass

          

    def print_class_name(self):

        print "this is class A"

          

      

class B(A):

      

    def __init__(self):

        pass

          

if __name__ == "__main__":

    class_b = B()

    class_b.print_class_name()

            上面代码首先定义了一个名为“A”的类,包含一个名为“print_class_name”的方法。然后,定义一个名为“B”的类,继承“A”,同时继承了“A”类的“print_class_name”的方法。

            此时“A”类为“B”类的父类或者叫基类,“B”类是“A”类的子类,子类会继承父类的所有公共方法。

            (2).意义:

                一字记之曰“懒!”(感叹号不算字)我始终相信赖人才能推动科学进步。

                言归正传,假如你要写一个老王类,包含年龄、性别等方法,后面还要写一个老王的儿子小王类,也有年龄、性别等方法

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

class FatherWang:

      

    def __init__(self, age=43, sex='man'):

        self.a = age

        self.s = sex

          

    def age(self):

        print self.a

          

    def sex(self):

        print self.s

          

class SonWang:

      

    def __init__(self, age=13, sex='man'):

        self.a = age

        self.s = sex

          

    def age(self):

        print self.a

          

    def sex(self):

        print self.s

          

if __name__ == "__main__":

    father = FatherWang(43, "man")

    father.age()

    father.sex()

      

    son = SonWang(13, "man")

    son.age()

    son.sex()

                你会发现两个类中有相同名称和功能的方法,这样写岂不是很重复很累?(尽管按键盘次数不算太多,我依然觉得很累)如果有继承就很好解决了。?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

class FatherWang:

      

    def __init__(self, age=43, sex='man'):

        self.a = age

        self.s = sex

          

    def age(self):

        print self.a

          

    def sex(self):

        print self.s

          

class SonWang(FatherWang):

      

    def __init__(self, age=13, sex='man'):

        FatherWang.__init(age, sex)

          

if __name__ == "__main__":

    father = FatherWang(43, "man")

    father.age()

    father.sex()

      

    son = SonWang(13, "man")

    son.age()

    son.sex()

               两者运行结果完全一样,但是使用继承方法却省了很多按键盘的次数。            

        3.经典类与新式类:

            (1)经典类写法:

class A:

    pass

            (2)新式类写法:

class A(object):

    pass

            可以看出,新式类和经典类的区别在于,是否继承object这个基类。object是所有类的父类。所以之前不带“(object)”的写法,属于经典类写法,加上“(object)”就是新式类的写法。

            (3).原因:这里我得吐槽一下Python的版本混乱。2.2版本之前只有经典类写法,这里有一个问题,代码如下

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

class A:

    pass

 

class B(object):

    pass

 

 

a = A()

b = B()

 

print a.__class__

print type(a)

print "----------"

print b.__class__

print type(b)

结果为:

__main__.A

<type 'instance'>

----------

<class '__main__.B'>

<class '__main__.B'>

        首先A类为经典类,B类为新式类。__class__属性和type()方法都是返回对象类型,那么问题来了,使用经典类的写法返回结果却不一致。因此在2.2版本之后出现了新式类来解决这个问题,自然,新式类和经典类还有更大的区别在后面说。另外在3.3版本中,无论使用哪种写法,python都会隐式的继承object,所以3.3版本不会再有经典类(在这里我只想问,早干什么去了!),但是鉴于3.3兼容性问题,貌似没有太多人用。

 

        4.方法重写与方法重载

            (1).方法重写:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

class FatherWang:

      

    def __init__(self, age=43, sex='man'):

        self.a = age

        self.s = sex

          

    def age(self):

        print self.a

          

    def sex(self):

        print self.s

          

    def name(self):

        print "Wang_yang"

          

          

class SonWang(FatherWang):

      

    def __init__(self, age=13, sex='man'):

        FatherWang.__init(age, sex)

          

    def name(self):

        print "Wang_xiaoming"

          

          

if __name__ == "__main__":

    father = FatherWang(43, "man")

    father.age()

    father.sex()

    father.name()

      

    son = SonWang(13, "man")

    son.age()

    son.sex()

    son.name()

            比继承写法(2)中的代码相比,两个类分别多了同名的方法“name”,之前说过子类会继承父类的方法,那么这时候两个类有相同名字的方法,冲突了,怎么处理?

            这个时候,就叫方法重写。可以理解为,子类的“name”方法把父类的“name”方法覆盖了,重新写了,所以调用子类的“name”方法时,会以子类的为准(尽管这种理解并不准确,但是可以很好解释“方法重写”这个名词,后面会讲到正确理解)。

           注意下面的代码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

class FatherWang:

 

    def __init__(self, age=43, sex="man"):

        self.a = age

        self.s = sex

        print "I am FatherWang"

          

    def age(self):

        print "Father age:"+str(self.a)

 

    def sex(self):

        print "Father sex:"+str(self.s)

 

class MotherLi:

 

    def __init__(self, age=40, sex="woman"):

        self.a = age

        self.s = sex

        print "I am MotherLi"

 

    def age(self):

        print "Mother age:"+str(self.a)

 

    def sex(self):

        print "Mother sex"+str(self.s)

 

class SonWang(FatherWang, MotherLi):

 

    def __init__(self, age=13, sex="man"):

        FatherWang.__init__(self, age, sex)

        MotherLi.__init__(self, age, sex)

        print "I am SonWang"

 

 

if __name__ == "__main__":

    son = SonWang()

    son.age()

    son.sex()

 执行结果:

I am FatherWang

I am MotherLi

I am SonWang

Father age:13

Father sex:man

 

            在之前代码上稍作修改,另外增加了一个MotherLi的类,SonWang类继承了FatherWang类和MotherLi类。注意,这是经典类的写法。

            首先,我们知道了python多继承的写法,就是在括号中上一个父类后面加个逗号,然后再写上下一个父类的名字:

 

class SonWang(FatherWang, MotherLi):

            其次,FatherWang类和MotherLi类,都有名为age和sex方法,SonWang类为什么会继承FatherWang类的方法呢?那么把SonWang类的继承顺序改一下

 

class SonWang(MotherLi, FatherWang):

就会发现继承的是MotherLi类的方法。

            通过结果可知,是按照继承的顺序。

            让我们把代码结构变得更发杂一些吧,我想会崩溃的,哈哈哈

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

class Grandfather:

    def __init__(self, age=73, sex="man"):

        self.a = age

        self.s = sex

        print "I am Grandfather"

 

    def age(self):

        print "Grandfather age:"+str(self.a)

 

    def sex(self):

        print "Grandfather sex:"+str(self.s)

 

    def Interesting(self):

        print "Grandfather Interesting"

          

class Grandmother:

    def __init__(self, age=70, sex="woman"):

        self.a = age

        self.s = sex

        print "I am Grandmother"

 

    def age(self):

        print "Grandmother age:"+str(self.a)

 

    def sex(self):

        print "Grandmother sex:"+str(self.s)

 

    def Interesting(self):

        print "Grandmother Interesting"

 

 

class FatherWang(Grandfather, Grandmother):

    def __init__(self, age=43, sex="man"):

        self.a = age

        self.s = sex

        Grandfather.__init__(self, age, sex)

        Grandmother.__init__(self, age, sex)

        print "I am FatherWang"

          

    def age(self):

        print "Father age:"+str(self.a)

 

    def sex(self):

        print "Father sex:"+str(self.s)

 

class MotherLi(Grandfather, Grandmother):

    def __init__(self, age=40, sex="woman"):

        self.a = age

        self.s = sex

        Grandfather.__init__(self, age, sex)

        Grandmother.__init__(self, age, sex)

        print "I am MotherLi"

 

    def age(self):

        print "Mother age:"+str(self.a)

 

    def sex(self):

        print "Mother sex"+str(self.s)

 

    def Interesting(self):

        print "MotherLi Interesting"

 

class SonWang(FatherWang, MotherLi):

    def __init__(self, age=13, sex="man"):

        FatherWang.__init__(self, age, sex)

        MotherLi.__init__(self, age, sex)

        print "I am SonWang"

          

if __name__ == "__main__":

    son = SonWang()

    son.age()

    son.sex()

    son.Interesting()

执行结果:            

I am Grandfather

I am Grandmother

I am FatherWang

I am Grandfather

I am Grandmother

I am MotherLi

I am SonWang

Father age:13

Father sex:man

Grandfather Interesting

 

            话说,我自己都有点儿晕。简单来讲,就是儿子继承了老爸、老妈,然后老爸继承了爷爷、奶奶,妈妈继承了老爷、姥姥。(真是一大家子啊)

            通过执行结果可知,儿子类先找到老爸类,然后再找老爸类的第1个父类爷爷类,此时发现爷爷类没有父类了,那么执行初始化。然后还要继续找到老爸类的第2个父类奶奶类,此时发现奶奶类没有父类了,执行初始化。此时老爸类的所有父类都初始化完成,初始化自己。然后开始找妈妈类……

            那么为什么Interesting方法会使用爷爷类的呢?奶奶类、老爷类、姥姥类都有啊?首先儿子类没有Interesting方法,会先找第1个父类老爸类。发现老爸类也没有,再找老爸类的第1个父类,发现找到了,那么就直接调用不再往下找了。

 

            结论:经典类的多继承,按照继承顺序查找。即,从左到右,从下到上的方式。注意,只有经典类是这样的!

 

            (2).新式类的多继承:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

class Grandfather(object):

    def __init__(self, age=73, sex="man"):

        self.a = age

        self.s = sex

        print "I am Grandfather"

 

    def age(self):

        print "Grandfather age:"+str(self.a)

 

    def sex(self):

        print "Grandfather sex:"+str(self.s)

 

    def Interesting(self):

        print "Grandfather Interesting"

          

class Grandmother(object):

    def __init__(self, age=70, sex="woman"):

        self.a = age

        self.s = sex

        print "I am Grandmother"

 

    def age(self):

        print "Grandmother age:"+str(self.a)

 

    def sex(self):

        print "Grandmother sex:"+str(self.s)

 

    def Interesting(self):

        print "Grandmother Interesting"

 

 

class FatherWang(Grandfather, Grandmother):

    def __init__(self, age=43, sex="man"):

        self.a = age

        self.s = sex

        Grandfather.__init__(self, age, sex)

        Grandmother.__init__(self, age, sex)

        print "I am FatherWang"

          

    def age(self):

        print "Father age:"+str(self.a)

 

    def sex(self):

        print "Father sex:"+str(self.s)

 

class MotherLi(Grandfather, Grandmother):

    def __init__(self, age=40, sex="woman"):

        self.a = age

        self.s = sex

        Grandfather.__init__(self, age, sex)

        Grandmother.__init__(self, age, sex)

        print "I am MotherLi"

 

    def age(self):

        print "Mother age:"+str(self.a)

 

    def sex(self):

        print "Mother sex"+str(self.s)

 

    def Interesting(self):

        print "MotherLi Interesting"

 

class SonWang(FatherWang, MotherLi):

    def __init__(self, age=13, sex="man"):

        FatherWang.__init__(self, age, sex)

        MotherLi.__init__(self, age, sex)

        print "I am SonWang"

          

if __name__ == "__main__":

    son = SonWang()

    son.age()

    son.sex()

    son.Interesting()

 

 

 

执行结果:

I am Grandfather

I am Grandmother

I am FatherWang

I am Grandfather

I am Grandmother

I am MotherLi

I am SonWang

Father age:13

Father sex:man

MotherLi Interesting

 

            奇怪,此时调用Interesting方法,返回的竟然是MotherLi类的。因为是这样的,使用新式类时,python发现SonWang类的两个父类FatherWang类和MotherLi类有相同的父类,那么找到SonWang类的第1个父类FatherWang类时,发现没有,便会去找SonWang类的第2个父类MotherLi类,找到了便执行。如果MotherLi类也没有,才会继续到Grandfather类找。

 

            结论1:新式类多继承时,当子类的多个父类拥有相同第二级父类时,会先找子类的父类,如果都没有子类调用的方法,再按照子父类顺序进行下一级父类查找。

            那么很有趣的事情发生了,代码如下

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

class FatherGrandfather(object):

    def __init__(self, age=73, sex="man"):

        self.a = age

        self.s = sex

        print "I am FatherGrandfather"

 

    def age(self):

        print "FatherGrandfather age:"+str(self.a)

 

    def sex(self):

        print "FatherGrandfather sex:"+str(self.s)

 

    def Interesting(self):

        print "FatherGrandfather Interesting"

          

class FatherGrandmother(object):

    def __init__(self, age=70, sex="woman"):

        self.a = age

        self.s = sex

        print "I am FatherGrandmother"

 

    def age(self):

        print "FatherGrandmother age:"+str(self.a)

 

    def sex(self):

        print "FatherGrandmother sex:"+str(self.s)

 

    def Interesting(self):

        print "FatherGrandmother Interesting"

 

class MotherGrandfather(object):

    def __init__(self, age=73, sex="man"):

        self.a = age

        self.s = sex

        print "I am MotherGrandfather"

 

    def age(self):

        print "MotherGrandfather age:"+str(self.a)

 

    def sex(self):

        print "MotherGrandfather sex:"+str(self.s)

 

    def Interesting(self):

        print "MotherGrandfather Interesting"

 

class MotherGrandmother(object):

    def __init__(self, age=70, sex="woman"):

        self.a = age

        self.s = sex

        print "I am MotherGrandmother"

 

    def age(self):

        print "MotherGrandmother age:"+str(self.a)

 

    def sex(self):

        print "MotherGrandmother sex:"+str(self.s)

 

    def Interesting(self):

        print "MotherGrandmother Interesting"

 

class FatherWang(FatherGrandfather, FatherGrandmother):

    def __init__(self, age=43, sex="man"):

        self.a = age

        self.s = sex

        FatherGrandfather.__init__(self, age, sex)

        FatherGrandmother.__init__(self, age, sex)

        print "I am FatherWang"

          

    def age(self):

        print "Father age:"+str(self.a)

 

    def sex(self):

        print "Father sex:"+str(self.s)

 

class MotherLi(MotherGrandfather, MotherGrandmother):

    def __init__(self, age=40, sex="woman"):

        self.a = age

        self.s = sex

        MotherGrandfather.__init__(self, age, sex)

        MotherGrandmother.__init__(self, age, sex)

        print "I am MotherLi"

 

    def age(self):

        print "Mother age:"+str(self.a)

 

    def sex(self):

        print "Mother sex"+str(self.s)

 

 

class SonWang(FatherWang, MotherLi):

    def __init__(self, age=13, sex="man"):

        FatherWang.__init__(self, age, sex)

        MotherLi.__init__(self, age, sex)

        print "I am SonWang"

          

if __name__ == "__main__":

    son = SonWang()

    son.age()

    son.sex()

    son.Interesting()

执行结果:

I am FatherGrandfather

I am FatherGrandmother

I am FatherWang

I am MotherGrandfather

I am MotherGrandmother

I am MotherLi

I am SonWang

Father age:13

Father sex:man

FatherGrandfather Interesting

            执行结果出乎意料啊,是新式类啊,居然调用的不是MotherL的Interesting方法。

 

            结论2:如果新式类多继承时,子类的多个父类没有相同的二级父类时,依然会按照经典类查找方式查找。

 

            (3).关键字:super

 

原文:https://www.2cto.com/kf/201510/447042.html

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值