测试题:
0.继承机制给程序员带来的最明显的好处是?
可以有效的减少代码量。如果一个类A继承自另一个类B,就把A叫做B的子类,把B称作A的父类。A会拥有拥有的全部属性和方法,不需要对于A再进行相似编辑。然而在子类编程的过程中,也可以重新定义某些定义,并重写某些方法,(覆盖原来父类所拥有的的属性和方法,使得子类与父类拥有不同的功能。)在子类中追加新的属性和方法是一种常用的操作。
1.如果按一下方式重写魔法方法__init__结果会怎样?
1 class MyClass: 2 def __init__(self): 3 return "I love fish !"
会报错!因为__init__特殊方法不应当返回除了None以外的任何对象。
可以实现如下操作:
1 方法一: 2 class Myclass: 3 def __init__(self): 4 print("hello") 5 方法二: 6 class Myclass: 7 def __init__(self): 8 return 9 方法三:(会报错) 10 class Myclass: 11 def __init__(self): 12 return 8938
错误如下:
1 Traceback (most recent call last): 2 File "<pyshell#22>", line 1, in <module> 3 my = Myclass1() 4 TypeError: __init__() should return None, not 'int', not 'str'
2.当子类定义了与相同名字的属性方法时,Python是否会自动删除父类的相关属性或方法?
不会。只是子类中重新定义的属性方法在子类中会覆盖与之相同的父类的属性方法,在子类中此属性方法会有另一种表现。但父类还有此属性方法,只是子类“看不到”。
3.假设已经有鸟类的定义,现在我要定义企鹅类继承于鸟类,但我们都知道企鹅是不会飞的,我们该如何屏蔽父类(鸟类)中飞的方法?
覆盖父类方法,例如将函数体内容写pass,这样调用fly方法就没有任何显示l了。
1 class Bird: 2 def fly(self): 3 print("i can fly") 4 class Penguin(Bird): 5 def fly(self): 6 print("i can not fly") 7 # 或者 pass 8 9 bird = Bird() 10 penguin = Penguin() 11 bird.fly() 12 penguin.fly()
4.super函数有什么“超级的地方”?
super函数超级的地方在于:你不需要明确给出任何基类的名字,他会自动帮您找出所有的基类以及对应的方法。由于你不用给出基类的名字,这就意味着你如果需要改变了类继承关系,你只要改变class语句里的父类即可,而不必在大量的代码中去修改所有被继承的方法。
5.多重继承使用不当会导致重复调用的问题,请分析一下代码在实际编程中有可能导致什么问题?
1 class A(): 2 def __init__(self): 3 print("进入A") 4 print("离开A") 5 class B(A): 6 def __init__(self): 7 print("进入B") 8 A.__init__(self) 9 print("离开B") 10 class C(A): 11 def __init__(self): 12 print("进入C") 13 A.__init__(self) 14 print("离开C") 15 class D(B,C): 16 def __init__(self): 17 print("进入D") 18 B.__init__(self) 19 C.__init__(self) 20 print("离开D")
多重继承容易造成重复调用的问题。在上面的代码中主要体现在D类的调用上。
关于危害,小甲鱼是这样说的:假设A中的初始化方法中有一个计数器,那这样D一实例化,A的计数器就跑两次(如果遇到多个钻石结构还可能会耕读,调用更复杂)。这样会很明显是不符合程序设计的初衷的。程序用该是可控的,而不能受到继承关系影响)。
上面的代码在调用D时,结果输出是这样的:
1 >>> a = A() 2 in A 3 out A 4 >>> b = B() 5 in B 6 in A 7 out A 8 out B 9 >>> c = C() 10 in C 11 in A 12 out A 13 out C 14 >>> d = D() 15 in D 16 in B 17 in A 18 out A 19 out B 20 in C 21 in A 22 out A 23 out C 24 out D
6.如何解决上一题中出现的问题?
1 class A: 2 def __init__(self): 3 print("A1") 4 print("A2") 5 class B(A): 6 def __init__(self): 7 print("B1") 8 super().__init__() 9 print("B2") 10 class C(A): 11 def __init__(self): 12 print("C1") 13 print("C2") 14 class D(B,C): 15 def __init__(self): 16 print("D1") 17 super().__init__() 18 print("D2") 19 20 实现结果如下: 21 >>> d = D() 22 D1 23 B1 24 C1 25 C2 26 B2 27 D2 28 29 30 class A: 31 def __init__(self): 32 print("A1") 33 print("A2") 34 class B(A): 35 def __init__(self): 36 print("B1") 37 super().__init__() 38 print("B2") 39 class C(A): 40 def __init__(self): 41 print("C1") 42 super().__init__() 43 print("C2") 44 class D(B,C): 45 def __init__(self): 46 print("D1") 47 super().__init__() 48 print("D2") 49 50 实现结果如下: 51 >>> D = D() 52 D1 53 B1 54 C1 55 A1 56 A2 57 C2 58 B2 59 D2
关于super()的用法以及细节可以参考:
https://www.cnblogs.com/miyauchi-renge/p/10923127.html
动动手:
0.定义一个点(Point)类和直线(Line)类,使用getLen方法可以获得直线的长度。
1 import math 2 class Point: 3 def __init__(self,x, y): 4 self.x = x 5 self.y = y 6 def getX(self): 7 return self.x 8 def getY(self): 9 return self.y 10 11 class Line: 12 def __init__(self,p1,p2): 13 self.x = p1.getX()-p2.getX() 14 self.y = p1.getY()-p2.getY() 15 self.len = math.sqrt(self.x*self.x+self.y*self.y) 16 def getLen(self): 17 return self.len
1.展示一个你的作品,你已经掌握了大部分Python的基础知识,花一个星期做一个好的作品。(可以是游戏、应用软件、脚本),使用上学过的任何东西(类,字典,函数,列表···)来改进你的程序。