类变量
类方法
静态方法
单继承
封装
多态
类变量
类变量是类的属性,此属性属于类,不属于类的实例
作用:
通常用来存储该类创建的对象的共有属性
说明:
类变量可以通过该类直接访问
类变量可以通过类的实例直接访问(取值)
类变量可以通过此类的对象的__class__属性间接访问
示例见:
#此示例示意类变量的定义方法,和用法 class car: total_count=0 #创建类变量 print(car.total_count) car.total_count+=100 c1=car() print(c1.total_count) #100借助对象访问类变量 c1.total_count=999 #创建实例变量 print(c1.total_count) #999 print(car.total_count) 100 #类变量可以通过此类的对象的___class__属性间接访问 c1.__class__.total_count=8888 print(c1.total_count) #999 print(car.total_count) #8888 class car: total_count=0 def __init__(self,info): self.info=info self.__class__.total_count+=1 def __del__(self): print('汽车',self.info,'被销毁') self.__class__.total_count-=1 c1=car('byd e6') c2=car('jili c7') print('当前有%d个汽车对象'%car.total_count) #2 del c2 print(car.total_count) 当前有2个汽车对象 汽车 jili c7 被销毁 1 汽车 byd e6 被销毁j
类的文档字符串:
类内第一个没有赋值给变量的字符串为文档字符串
类的文档字符串可以用类的 __doc__ 属性访问
类的 __slots__ 列表
作用:
1. 限定一个类创建的实例只能有固定的实例变量(实例属性)
2. 不允许对象添加列表以外的实例属性
3. 防止用户因错写属性名称而发生错误
说明:
1. __slots__属性是一个列表,列表的值是字符串
2. 含有__slots__属性的类所创建的对象没有__dict__属性,即此实例不用字典来存储实例属性
示例见:
class Human: #限制Human类的对象只能有'name',和'age'属性,不能有其他属性 __slots__=['name','age'] def __init__(self,n,a): self.name,self.age=n,a def show_info(self): print(self.name,self.age) s1=Human('tarena',15) s1.show_info() # s1.Age=16 s1.show_info() print(s1.__slots__)
类方法 @classmethod
类方法是用于描述类的行为的方法,类方法属于类,不属于该类创建的实例对象
说明:
1. 类方法需要使用@classmethod装饰器定义
2. 类方法至少有一个形参,第一个形参用于绑定类,约定写为'cls'
3. 类和该类的实例都可以调用类方法
4. 类方法不能访问此类创建的对象的实例属性
示例见:
#此示例示意类方法的定义和调用 class A: v=0 @classmethod def get_v(cls): return cls.v @classmethod def set_v(cls,value): cls.v=value #设置类变量 print(A.v) #直接访问类变量 value=A.get_v() # print('value=',value) #0 A.set_v(999) print(A.get_v())
静态方法@staticmethod
静态方法是定义在类的内部的函数,此函数的作用域是类的内部
说明:
1. 静态方法需要使用@staticmethod装饰器定义
2. 静态方法与普通函数定义相同,不需要传入'self'和'cls' 参数
3. 静态方法只能凭借该类或类的实例调用
4. 静态方法不能访问类变量和实例变量
示例见:
#此示例示意静态方法的定义和应用 class A: @staticmethod def myadd(a,b): '''这是静态方法''' return a+b #用类来调用静态方法 print(A.myadd(100,200)) #300 a=A() #用此类的实例来调用今天方法 print(a.myadd(100,200))
1. 用类来描述一个学生的信息(可以修改之前写的Student类)
class Student:
.... 以下自己实现
学生信息有:
姓名, 年龄, 成绩
将这些学生对象存于列表中,可以任意添加和删除学生信息.
1) 打印出学生的个数
2) 打印出所有学生的平均成绩
3) 打印出所有学生的平均年龄
(建议用列表的长度来计算学生的个数)
继承 (inhertance) 和 派生 (derived)
继承是从已有的类中派生出新的类,新类具有原类的属性和行为,并能扩展新的能力
派生类就是从一个已有类中衍生出新类,在新的类上可以添加新的属性和行为
作用:
1. 用继承派生机制,可以将一些共有功能加在基类中,实现代码的共享
2. 在不改变基类代码的基础上改变原有类的功能
名词:
基类(base class),超类(super class), 父类(father class)
派生类(derived class), 子类(child class))
单继承
语法:
class 类名(基类名):
语句块
说明:
单继承是指派生类由一个基类衍生出来
示例见:
class Human: '''此类用于描述人类的共性''' def say(self,what): print('说:',what) def walk(self,distance): print('走了',distance,'公里') h1=Human() h1.say('您好') h1.walk(5) class Student(Human): def study(self,subject): print('正在学习:',subject) s1=Student() s1.say('学习优点类') s1.study('python') class Teacher(Human): def teach(self,subject): print("正在教:",subject) s2=Teacher() s2.teach('继承/派生') s2.say('放假了')
继承说明:
Python3任何类都直接或间接的继承自object类
object类是一切类的超类
类的 __base__属性
作用:
用来绑定此类的基类
python3中的内建内继承关系见:
>>> help(__builtins__)
覆盖 override
什么是覆盖:
覆盖是指在有继承关系的类中,子类中实现了与基类同名的方法,在子类的实例调用该方法时,实际调用的是子类中覆盖版本,这种现象叫做覆盖
示例见:
# override.py # 此示例示意覆盖的语法 class A: def work(self): print("A.work被调用") class B(A): def work(self): '''此方法会覆盖父类的work方法''' print("B.work被调用") b = B() b.work() # B.work被调用 a = A() a.work() # A.work被调用
子类对象显式调用基类方法的方式:
基类名.方法名(实例, 实际调用传参...)
super函数
super(cls, obj) 返回绑定超类的实例(要求obj必须是cls类型的实例)
super() 返回绑定超类的实例,等同于super(__class__, 实例方法的第一个参数) 必须在方法内调用
作用:
借助super() 返回实例间接调用父类的覆盖方法
示例见:
# super.py # 此示例示意用super函数显式的调用被覆盖的方法 class A: def work(self): print("A.work被调用") class B(A): def work(self): '''此方法会覆盖父类的work方法''' print("B.work被调用") def mywork(self): # 调用自己(B类)的方法 self.work() # 调用父类(A类)的方法 super(B, self).work() super().work() b = B() # b.work() # B.work被调用 # # A.work(b) # A.work被调用 # super(B, b).work() # A.work被调用 b.mywork()
显式调用基类的初始化方法:
当子类中实现了__init__ 方法,基类的实始化方法并不会被调用,此时需要显式调用基类的初始化方法
示例见:
# super_init.py # 此示例示意用super函数显式调用基类的初始化方法 class Human: def __init__(self, n, a): self.name = n self.age = a print("Human.__init__被调用") def show_info(self): print("姓名:", self.name) print("年龄:", self.age) class Student(Human): def __init__(self, n, a, s=0): super(Student, self).__init__(n, a) self.score = s print("Student.__init__被调用") def show_info(self): # 此处的代码自己完成 super().show_info() print("成绩:", self.score) s = Student("小张", 20, 100) s.show_info()