一、魔术函数
在Python中,xx()的函数叫做魔法函数,指的是具有特殊功能或者有特殊含义的函数,而且这些函数都是在某种情况下自动调用的。
eg: init函数
__init__() :对象的初始化函数,在创建一个对象的时默认被调用,不需要手动调用
__init__(self):中的self参数,不需要开发者传递,在Python解释器会自动把当前的对象引用传递过去。
class People(object):def __init__(self,name,age):self.name=nameself.age=agereturndef __str__(self):return self.name +":"+str(self.age)def __lt__(self, other):return self.name < other.name if self.name != other.name else self.ageprint("\t".join([str(item) for item in sorted([People("abc", 18), People("abe", 19), People("abe", 12), People("abc", 17)])]))
打印的结果为:
abc:17 abc:18 abe:12 abe:19
二、类属性和实例属性
(1)、类属性: 就是类所拥有的属性,它被该类的所有实例对象所共有。
(2)、实例属性:就是单个对象或者实例才能拥有的属性。
1、类属性
(1)、记录的某项数据始终保持一致时,则定义类属性。
(2)、实例属性要求每个对象为其单独开辟一份内存空间来记录数据,而类属性为全类所占有,仅占用一份内存,更加节省内存空间。
class People(object):name="person"def __init__(self,name,age):self.name=nameself.age=agereturndef __str__(self):return self.name +":"+str(self.age)def __lt__(self, other):return self.name < other.name if self.name != other.name else self.ageprint(People.name)
print(People("Tom", 12))
打印的结果为:
person
Tom:12
2、类函数
需要用装饰器@classmethod来标识其为类函数,对于类函数,第一个参数必须是类(当前类),一般以cls作为第一个参数,但是:也可以命名其他的。一般习惯上都用cls。
3、静态函数
需要通过装饰器@staticmethod来进行装饰,静态方法既不需要使用实例对象(如实例对象,实例属性),也不需要使用类对象(如类属性、类方法、创建实例等)时,定义静态方法
取消不需要的参数传递,有利于减少不必要的内存占用和性能消耗。
对于静态方法不用像类方法需要传递一个参数,可以直接通过类名.方法名的形式进行调用。当然也可以通过对象.类名的形式进行调用。
三、继承和重写
(1)、继承
python面向对象的继承指的是多个类之间的所属关系,即子类默认继承父类的所有属性和函数。
在python中,所有类默认继承object类,object类是顶级类或基类。
父类:
子类:在创建子类时将父类作为参数传入。
继承: 继承另一个类的所有方法和属性。
多继承:A类、B类是两个没有继承关系的类,C类即继承了A类又继承了B类。
print('---------------------多继承------------------------')
class A:passclass B:passclass C(A, B):pass
单继承:C类继承了B类,B类继承了A类,C、B、A是层次继承的关系。
print('---------------------单继承------------------------')
class Animal:passclass Animal1(Animal):pass
#父类
class Person:def __init__(mysillyobject, firstname, lastname):mysillyobject.name = firstnamemysillyobject.family = lastnamedef myfunc(abc):print("Hello my name is " + abc.name)#子类,继承
class Student(Person):def __init__(self, fname, year, lname):super().__init__(fname, lname) # 调用父类的属性赋值方法self.graduationyear = year #子类自己的属性def welcome(self):#子类自己的方法print("Welcome", self.name, self.family, "to the class of", self.graduationyear)x = Student("Elon", 2019, "Musk")
x.welcome()
(2)、重写
覆盖(Override):指在继承中,父类的有些方法在子类中不适用,子类重新定义。
注意:
若子类中被“覆盖”方法的参数类型不同,返回类型不一致,这不是覆盖,而是重载。覆盖要求参数类型必须一样,且返回类型必须兼容。总之,子类对象得保证能够执行父类的一切。
不能降低覆盖方法的存取权限,如public变成private。
若不希望父类的某个方法被子类覆盖,可以用final修饰该方法。甚至可以扩展到将类用final修饰,则其中所有的方法均不可覆盖,但不影响成员变量的赋值。
子类如何重写父类的方法?
前提:
规则一:重写方法不能比被重写方法限制有更严格的访问级别。
(但是可以更广泛,比如父类方法是包访问权限,子类的重写方法是public访问权限。)
规则二:参数列表必须与被重写方法的相同。
(需要注意的是如果子类方法的参数和父类对应的方法不一样,那就不是重写,而是重载)
规则三:返回类型必须与被重写方法的返回类型相同。
规则四:重写方法不能抛出新的异常或者比被重写方法声明的检查异常更广的检查异常。但是可以抛出更少,更有限或者不抛出异常。
规则五:不能重写被标识为final的方法。
规则六:如果一个方法不能被继承,则不能重写它。比如父类的私有方法就不能被重写。
如果子类能够继承父类的某个方法, 那么子类就能够重写这个方法。
# 如果子类中重写了父类方法
# 在使用子类对象调用方法时,会调用子类中重写的方法
class XiaoTianQuan(Dog):def fly(self):print("会飞")def bark(self):print("OKOK")class TuDog(Dog):def fly(self):passdef bark(self):print("小土狗")# 创建对象1
xtq = XiaoTianQuan()
xtq.bark()
xtq.drink()
xtq.sleep()# 创建对象2
tg = TuDog()
tg.bark()
tg.fly()
持续更新~