1、保护对象的属性 :类的私有属性
如果有一个对象,当需要对其进行修改属性时有两种方法:
a、对象名.属性名 = 数值 ---->直接修改
b、对象名.方法名()----->间接修改
为了更好的保存属性安全,即不能随意修改,一般的处理方式为:
a、将属性定义为私有属性
b、添加一个可以调用的方法,供调用
1 class Dog: 2 def __init__(self, new_name): 3 self.name = new_name 4 self.__age = 0 5 #定义了一个私有的属性,属性的名字是__age 6 7 #同过内部定义的方法设置私有属性 8 def set_age(self, new_age): 9 if new_age > 0 and new_age <= 100: 10 self.__age = new_age 11 12 else: 13 self.__age = 0 14 15 #通过内部定义的方法调用返回私有属性 16 def get_age(self): 17 return self.__age 18 19 20 dog = Dog('小白') 21 #dog.age = -10 22 #dog.name = '小黑' 23 #print(dog.age) 24 #print(dog.name) 25 26 dog.set_age(10)#通过内部方法设置私有属性 27 #age = dog.get_age() 28 #dog.__age = -10 29 30 print(dog.get_age())#通过内部方法调用私有属性 31 32 print(dog.__age)#直接调用报错,对象不存在调用属性
私有方法:
1 class Dog: 2 3 4 #私有方法 5 def __send_msg(self): 6 print('-------正在发送短信-------') 7 8 9 #公有方法 10 def send_msg(self, new_money): 11 if new_money > 10000: 12 self.__send_msg() 13 else: 14 print('余额不足,请先充值,自发短信……') 15 16 17 dog = Dog() 18 19 dog.send_msg(1000)#不满足判断条件无法调用私有方法 20 dog.send_msg(100000)#成功调用私有方法 21 dog.__send_msg()#报错无法直接调用,显示不存在方法
总结:
1、Python中没有像C++中public和private这些关键字来区别公有属性和私有属性
2、它是以属性命名方式来区分,如果在属性名前面加两个下划线‘--‘,则表示属性是私有属性,否则为公有属性(方法也是一样,方法名前加了2个下划线的话表示该方法为私有的,否则为共有的。)
2、__del__()方法
创建对象后,python解释器默认调用__init__()方法;
当删除一个对象时,python解释器也会默认调用一个方法,这个方法为__del__()方法
1 class Dog: 2 3 def __del__(self): 4 print("-----英雄over------") 5 6 dog1 = Dog() 7 dog2 = dog1 8 9 del dog1#不会调用 __del__方法,因为这个对象 还有其他的变量指向它,即 引用计算不是0 10 del dog2#此时会调用__del__方法,因为没有变量指向它了 11 print("====================") 12 13 #如果在程序结束时,有些对象还存在,那么python解释器会自动调用它们的__del__方法来完成清理工作
总结:
1、当有1个变量保存了对象的引用时,此对象的引用计数就会加1
2、当使用del删除变量指向的对象时,如果对象的引用计数不为1,比如3,那么此时只会让这个引用计数减1,即变量为2,当再次调用del时,再减,如果在调用del此时真的会把对象进行删除。
3、单继承
1、子类在继承的时候,在定义类时,小括号()中为父类的名字。
2、父类的属性、方法,会被继承给子类。
注意点:
1、私有的属性,不能通过对象直接访问,但是可以通过方法访问。
2、私有的方法,不能通过对象直接访问。
3、私有的属性、方法,不会被子类继承,也不能访问。
4、一般情况下,私有的属性、方法都是不对外公布的,往往用来做内部的事情,起到安全的总用。
4、多继承 python中是可以多继承, 父类的方法、属性,子类会继承
5、重写父类方法和调用父类方法
1、重写父类方法
所谓重写,就是子类中,有一个和父类相同名字的方法,在子类中的方法会覆盖掉父类中的同名方法。
2、调用父类的方法
方法1:父类名.方法名()
方法2:super().方法名()
6、多态
多态的概念是应用于Java和C#这一类强类型语言中,而Python崇尚“鸭子类型”
所谓多态:定义时的类型和运动时的类型不一样,此时就称为多态。
7、类属性、实例属性
类属性就是类对象所拥有的属性,它被所有的类对象的实例对象所共有,在内存中只存在一个副本,这个和C++中的静态成员变量有点类似。对于公有的类属性,在类外可以通过类对象和实例对象访问。
总结:如果需要在类外修改类属性,必须通过类对象去引用然后进行修改。如果通过实例对象去引用,会产生一个同名的实例属性,这种方式修改的是实例属性,不会影响到类属性,并且之后如果通过实例对象去引用该名称属性,实例属性会强制屏蔽掉类属性,即引用的是实例属性,除非删除了该实例属性。
8、静态方法和类方法
1、类方法
是类对象所拥有的方法,需要用修饰器@classmethod来标识其为类方法,对于类方法,第一个参数必须是类对象,一般一cls作为第一个参数(当然可以用其他名称的变量作为第一个参数,但是大部分人都习惯以cls作为第一个参数名字,就最好用cls),能够通过实例对象和类对象去访问。
类方法还一个用途就是可以对类属性进行修改:
2、静态方法
需要通过装饰器@staticmethod来修饰,静态方法不需要多定义参数
总结:
从类方法和实例方法以及静态方法的定义形式就可以看出来,类方法的第一个参数是类对象cls,那么通过cls引用的必定是类对象的属性和方法;而实例方法的第一个参数是实例对象self,那么通过 self引用的可能是类属性、也有可能是实例属性(这个需要具体分析),不过在存在相同名称的类属性和实例属性的情况下,实例属性优先级更高。静态方法中不需要额外定义参数,因此在静态方法中引用类属性的话,必须通过类对象来引用。