__del__方法
创建对象后,python解释器默认调用__init__()方法;
当删除一个对象时,python解释器也会默认调用一个方法,这个方法为__del__()方法
总结:
当有1个变量保存了对象的引用时,此对象的引用计数就会加1
当使用del删除变量指向的对象时,如果对象的引用计数不会1,比如3,那么此时只会让这个引用计数减1,即变为2,当再次调用del时,变为1,如果再调用1次del,此时会真的把对象进行删除,__del__会被调用
继承
将共性的内容放在父类中,子类只需要关注自己特有的内容
python中所有的内容都是对象,所有的对象都直接或间接继承了object
在程序中,继承描述的是事物之间的所属关系,例如猫和狗都属于动物,程序中便可以描述为猫和狗继承自动物;同理,波斯猫和巴厘猫都继承自猫,而沙皮狗和斑点狗都继承足够。
说明:
虽然子类没有定义__init__方法,但是父类有,所以在子类继承父类的时候这个方法就被继承了,所以只要创建Bosi的对象,就默认执行了那个继承过来的__init__方法
总结:
子类在继承的时候,在定义类时,小括号()中为父类的名字
父类的属性、方法,会被继承给子类
class Animal:
'''
只是一个关于动物的类
'''
def __init__(self,name,color,breed):
'''
初始化动物的属性
name:动物名字
color:颜色
breed:品种
'''
self.name = name
self.color = color
self.breed = breed
def explain(self):
'''
这是一份关于此类的说明
'''
print('这是一个父类,用于描述动物的共有特征')
class Dog(Animal):
'''
这是一个关于狗的类
'''
def lookHouse(self):
'''
说明狗的用处的方法
'''
print('%s可以看家'%(self.name))
def __str__(self):
'''
打印狗狗的信息
'''
return 'name=%s,color=%s,breed=%s'%(self.name,self.color,self.breed)
class Cat(Animal):
'''
这是一个关于猫的类
'''
def catchMouse(self):
'''
说明猫的用处的方法
'''
print('%s可以捉老鼠'%(self.name))
def __str__(self):
'''
打印猫咪的信息
'''
return 'name=%s,color=%s,breed=%s'%(self.name,self.color,self.breed)
d1 = Dog('大黄','黑色','哈士奇')
d1.lookHouse()
print(d1)
d1.explain()
print('**************************************')
c1 = Cat('小白','白色','波斯猫')
c1.catchMouse()
print(c1)
c1.explain()
私有属性
私有的属性,不能通过对象直接访问,但是可以通过方法访问
私有的方法,不能通过对象直接访问
私有的属性、方法,不会被子类继承,也不能被访问
一般情况下,私有的属性、方法都是不对外公布的,往往用来做内部的事情,起到安全的作用
单继承,覆盖
单继承就是一个子类只继承一个父类
多继承
多继承,即子类有多个父类,并且具有它们的特征
多态
什么是封装?
类是一种封装,将属性和方法封装。
函数也是一种封装,将具有一定共的逻辑代码封装到一个函数中,使用的时候调用即可
提高代码的扩展性。
什么是继承?
将公共的(共性的)属性和方法放在父类中,子类只关注自己特有的属性和方法。
提高代码的扩展性。
什么是多态?
一个对象在不同的情况下,具有不同的形态,用于强类型语言。是使用在继承和接口中实现。
Python中有两种说法:
1、python支持多态,python是一个弱类型,本身一个变量名,可以存储任何类型的值,可以理解为多种形态
2、python不支持多态,多态本身是用于强类型语言的,python是一个弱类型,所以不支持多态
所谓多态:定义时的类型和运行时的类型不一样,此时就成为多态
python是一种弱类型语言,没有类型限制。
变量的类型永远是通过右侧的值判断的。
方法中的参数,传递任何值都行。但是要考虑方法内部的业务逻辑。
多态:
1、父类作为参数,可以传递父类和子类对象
2、接口作为参数,只能传递实现对象
所以有两种理解:
1、python不支持多态:
python是弱类型,没有类型限定,无法区分父和子,或者说接口和实现类
2、python处处是多态
python是弱类型,没有类型限定,传递任何内容都行
实例属性
在方法里通过self.属性 都是实例属性
类属性
直接在类中定义的,与方法平齐,不在方法里的属性就是 类属性
类方法
类对象所拥有的方法,需要用修饰器@classmethod(注解、元数据)来标识其为类方法,对于类方法,第一个参数必须是类对象,一般以cls作为第一个参数(当然可以用其他名称的变量作为其第一个参数,但是大部分人都习惯以'cls'作为第一个参数的名字,就最好用'cls'了),能够通过实例对象和类对象去访问。
静态方法
需要通过修饰器@staticmethod来进行修饰,静态方法不需要多定义参数
总结:
从类方法和实例方法以及静态方法的定义形式就可以看出来,类方法的第一个参数是类对象cls,那么通过cls引用的必定是类对象的属性和方法;而实例方法的第一个参数是实例对象self,那么通过self引用的可能是类属性、也有可能是实例属性(这个需要具体分析),不过在存在相同名称的类属性和实例属性的情况下,实例属性优先级更高。静态方法中不需要额外定义参数,因此在静态方法中引用类属性的话,必须通过类对象来引用