1、构造方法__init__(self,):当创建这个类的实例时,系统会自动调用该方法,对实例属性进行初始化。当用户没有显示定义init构造方法的时候,系统会自动生成一个缺省的构造方法。
2、有关类方法、实例方法、静态方法;还有类属性、实例属性的解释都在下文有详细阐述
1、简述类方法和实例方法的区别
答:
(1)类方法声明之前要有一句@classmethod
(2)类方法第一个参数是cls;实例方法第一个参数是self
(3)类方法可以使用类名调用和实例调用;实例方法只能使用实例调用。
(4)类方法,因为没有参数self,所以里面涉及的属性都是类属性,也就是实例之间共享的可以使用cls进行修改类属性,也可以使用类名修改;实例方法,既可以通过self操作实例属性,也可以通过self或类名访问类属性使用类名修改类属性(不能使用self修改类属性)。
2、简述Python继承和JAVA中继承的区别
3、类属性和实例属性的区别。
类属性可以通过类名和实例进行访问,但是私有类属性在外部不能直接通过类名和实例访问。
类属性只能通过类名进行修改,如果使用实例进行修改,它实际上是创建了一个同名的实例属性,后续使用这个实例访问的就是这个新生成的,除非把这个实例属性删除才能恢复原样。
实例属性每个实例不共享值,访问和修改只能通过实例进行操作。
在函数定义中也是如此,在实例方法中修改类属性也是得用类名。
4、方法分为静态方法、类方法和实例方法
静态方法,就是参数不含self和cls,只能使用类名进行调用,因为没有了self,也就不会涉及到实例属性,里面的属性就会是类属性,所以直接使用类名进行调用也不会出错。
类方法第一个参数是cls,可以使用类名调用,也可以使用实例调用。
实例方法第一个参数是self,只能使用实例调用。
5、在声明类方法之前如果不写@classmethod,在修改类属性时就不会真正的修改。
没写@classmethod时:
写了@classmethod时:
私有类属性
没有关键字来限制私有类属性的定义,私有类属性的名字前面加两个下划线就行了。私有类属性的访问可以定义方法,其实也可以在外部访问。
class A():
__x = 7
def getx(self):
#使用方法,访问私有变量x
print("使用方法访问私有变量",self.__x)
a = A()
a.getx()
print("直接在外部访问,单下划线+类名+双下划线+私有类属性名",a._A__x)
a._A__x = 9
print("直接在外部访问,单下划线+类名+双下划线+私有类属性名",a._A__x)
使用方法访问私有变量 7
直接在外部访问,单下划线+类名+双下划线+私有类属性名 7
直接在外部访问,单下划线+类名+双下划线+私有类属性名 9
可以看到,python的私有机制是伪私有,python类是没有权限控制的,变量是可以被外部直接调用的。
关于面向对象的三大特点的理解
多态 | 可对不同类型的对象执行相同的操作 |
---|---|
封装 | 对外部隐藏有关对象工作原理的细节 |
继承 | 可以基于通用类创建出专用类 |
继承
class Son(Father)
多重继承class Son(Father1,Father2,)但是不建议使用多重继承
子类可以继承父类的任何属性和方法,其中私有变量也被继承了,但在外部访问的操作不是完全一致(具体看下方代码),父类中访问了私有变量的方法也被继承了,且可以正常使用。
class A():
__x = 7
def getx(self):
#使用方法,访问私有变量x
print("使用方法访问私有变量",self.__x)
class B(A):
pass
b = B()
b.getx() #使用方法访问私有变量 7
b._B__x #报错,'B' object has no attribute '_B__x'
b._A__x #正确,7
继承中,子类的init方法得调用父类的init方法的操作super().__init__()
class Animal():
"""动物类"""
def __init__(self,color=""):
#构造方法
self.color = color
def call(self):
#吼叫方法
print("This animal is calling.")
class Fish(Animal):
"""鱼类"""
def __init__(self,color="",tail=""):#重写init方法
#构造方法
super().__init__(color)
self.tail = tail
def call(self):#重写父类方法
#吼叫方法
print("This fish is calling.")
fish = Fish(color="red", tail="big")
print("这条鱼的颜色是",fish.color)
print("这条鱼的尾巴是",fish.tail)
fish.call()
这条鱼的颜色是 red
这条鱼的尾巴是 big
This fish is calling.
自动调用的方法
- __init__()创建对象时,自动调用
- __str__()打印该类对象时,自动调用
- __add__()对该类对象执行加法时,自动调用
- __sub__()减法
- __mul__()乘法
- __truediv__()除法
class xl:
def __init__(self,x=0,y=0,z=0):
self.x=x
self.y=y
self.z=z
def __str__(self):
#定义如何直接打印一个向量,而不是默认的打印引用值
display = "("+str(self.x)+","+str(self.y)+","+str(self.z)+")"
return display
def __add__(self,b):
#定义加法,
l=xl(self.x,self.y,self.z)
l.x=self.x+b.x
l.y=self.y+b.y
l.z=self.z+b.z
return l
l1=xl(9,5,9)
l2=xl(8,3,5)
print(l1+l2)
(17,8,14)
但是加法如果这样调用
print(l1+2)
print(3+l2)