类的语法
- 类的定义
1 class Dog(object): 2 3 print("hello,I am a dog!") 4 5 6 d = Dog() #实例化这个类, 7 #此时的d就是类Dog的实例化对象 8 9 #实例化,其实就是以Dog类为模版,在内存里开辟一块空间,存上数据,赋值成一个变量名
- 类的初始化
1 class Dog(object): 2 3 def __init__(self,name,dog_type): 4 self.name = name 5 self.type = dog_type 6 7 def sayhi(self): 8 9 print("hello,I am a dog, my name is ",self.name) 10 11 12 d = Dog('LiChuang',"京巴") 13 d.sayhi()
- 类的方法
__init__
方法 相当于构造函数
class Cat: """这是一个猫类""" def __init__(self): print("初始化方法")
__del__方法相当于析构函数
class Cat: def __init__(self, new_name): self.name = new_name print("%s 来了" % self.name) def __del__(self): print("%s 去了" % self.name)
- 定义私有 属性或方法
在 定义属性或方法时,在 属性名或者方法名前 增加 两个下划线
class Women: def __init__(self, name): self.name = name # 不要问女生的年龄 self.__age = 18 def __secret(self): print("我的年龄是 %d" % self.__age) xiaofang = Women("小芳") # 私有属性,外部不能直接访问 # print(xiaofang.__age) # 私有方法,外部不能直接调用 # xiaofang.__secret()
- 类的继承
1) 继承的语法
class 类名(父类名): pass
2)重写(override)
当 父类 的方法实现不能满足子类需求时,可以对方法进行 重写(override)
重写 父类方法有两种情况:
- 覆盖 父类的方法
- 对父类方法进行 扩展
1) 覆盖父类的方法
- 如果在开发中,父类的方法实现 和 子类的方法实现,完全不同
- 就可以使用 覆盖 的方式,在子类中 重新编写 父类的方法实现
具体的实现方式,就相当于在 子类中 定义了一个 和父类同名的方法并且实现
重写之后,在运行时,只会调用 子类中重写的方法,而不再会调用 父类封装的方法
2) 对父类方法进行 扩展
- 如果在开发中,子类的方法实现 中 包含 父类的方法实现
- 父类原本封装的方法实现 是 子类方法的一部分
- 就可以使用 扩展 的方式
- 在子类中 重写 父类的方法
- 在需要的位置使用
super().父类方法
来调用父类方法的执行 - 代码其他的位置针对子类的需求,编写 子类特有的代码实现
关于 super
- 在
Python
中super
是一个 特殊的类 -
super()
就是使用super
类创建出来的对象 - 最常 使用的场景就是在 重写父类方法时,调用 在父类中封装的方法实现
class Dog(): def bark(self): print("汪汪汪") class XiaoTianQuan(Dog): def bark(self): #子类特有需求 print("像神一样叫...") #使用super()调用父类中的方法 super().bark()
完整例子
class SchoolMember(object): members = 0 #初始学校人数为0 def __init__(self,name,age): self.name = name self.age = age def tell(self): pass def enroll(self): '''注册''' SchoolMember.members +=1 print("\033[32;1mnew member [%s] is enrolled,now there are [%s] members.\033[0m " %(self.name,SchoolMember.members)) def __del__(self): '''析构方法''' print("\033[31;1mmember [%s] is dead!\033[0m" %self.name) class Teacher(SchoolMember): def __init__(self,name,age,course,salary): super(Teacher,self).__init__(name,age) self.course = course self.salary = salary self.enroll() def teaching(self): '''讲课方法''' print("Teacher [%s] is teaching [%s] for class [%s]" %(self.name,self.course,'s12')) def tell(self): '''自我介绍方法''' msg = '''Hi, my name is [%s], works for [%s] as a [%s] teacher !''' %(self.name,'Oldboy', self.course) print(msg) class Student(SchoolMember): def __init__(self, name,age,grade,sid): super(Student,self).__init__(name,age) self.grade = grade self.sid = sid self.enroll() def tell(self): '''自我介绍方法''' msg = '''Hi, my name is [%s], I'm studying [%s] in [%s]!''' %(self.name, self.grade,'Oldboy') print(msg) if __name__ == '__main__': t1 = Teacher("Alex",22,'Python',20000) t2 = Teacher("TengLan",29,'Linux',3000) s1 = Student("Qinghua", 24,"Python S12",1483) s2 = Student("SanJiang", 26,"Python S12",1484) t1.teaching() t2.teaching() t1.tell()
- 多继承
class 子类名(父类名1, 父类名2...) pass
Python 中的 MRO —— 方法搜索顺序(知道)
-
Python
中针对 类 提供了一个 内置属性__mro__
可以查看 方法 搜索顺序 - MRO 是
method resolution order
,主要用于 在多继承时判断 方法、属性 的调用 路径
print(C.__mro__)
输出结果
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
- 在搜索方法时,是按照
__mro__
的输出结果 从左至右 的顺序查找的 - 如果在当前类中 找到方法,就直接执行,不再搜索
- 如果 没有找到,就查找下一个类 中是否有对应的方法,如果找到,就直接执行,不再搜索
- 如果找到最后一个类,还没有找到方法,程序报错
Python3全是广度优先继承
Python2是经典类是深度优先、新型类是广度优先
- 多态
多态 不同的 子类对象 调用相同的 父类方法,产生不同的执行结果
- 以 继承的子类重写父类方法 为前提
- 例子:
class Dog(object): def __init__(self, name): self.name = name def game(self): print("%s 蹦蹦跳跳的玩耍..." % self.name) class XiaoTianDog(Dog): def game(self): print("%s 飞到天上去玩耍..." % self.name) class Person(object): def __init__(self, name): self.name = name def game_with_dog(self, dog): print("%s 和 %s 快乐的玩耍..." % (self.name, dog.name)) # 让狗玩耍 dog.game() # 1. 创建一个狗对象 # wangcai = Dog("旺财") wangcai = XiaoTianDog("飞天旺财") # 2. 创建一个小明对象 xiaoming = Person("小明") # 3. 让小明调用和狗玩的方法 xiaoming.game_with_dog(wangcai)
class Animal(object): def __init__(self, name): # Constructor of the class self.name = name def talk(self): # Abstract method, defined by convention only raise NotImplementedError("Subclass must implement abstract method") class Cat(Animal): def talk(self): print('%s: 喵喵喵!' %self.name) class Dog(Animal): def talk(self): print('%s: 汪!汪!汪!' %self.name) def func(obj): #一个接口,多种形态 obj.talk() c1 = Cat('小晴') d1 = Dog('李磊') func(c1) func(d1)
另一种更简便的形式
class Animal(object): def __init__(self, name): # Constructor of the class self.name = name def talk(self): # Abstract method, defined by convention only raise NotImplementedError("Subclass must implement abstract method") ###该写成类内的形式 @staticmethod def func(obj): # 一个接口,多种形态 obj.talk() class Cat(Animal): def talk(self): print('%s: 喵喵喵!' % self.name) class Dog(Animal): def talk(self): print('%s: 汪!汪!汪!' % self.name) c1 = Cat('小晴') d1 = Dog('李磊') Animal.func(c1)