1.类成员
1.类变量
- 类的成员变量描述对象的属性值根据对象不同会产生区别,此时类变量称为实例变量
- 类变量的成员变量描述对象的属性值根据对象的不同不会产生区别,称此类变量为类变量
- 类变量是归属类的,实例变量是归属对象的
- 类变量书写在类定义的里面,实例变量书写在__init__方法中
class Dog: var = "都是狗" #类变量 定义在类里 # 所以的对象都有这个变量值 def __init__(self, name, age): # 对象变量 定义在init里 self.name = name self.age = age# 类名.变量名 方式访问类变量# 类名.变量名 = 变量值 方式修改复制代码
类变量名的访问
1.类名.类变量名(推荐)
2.对象名.类变量名
类变量名的修改
类名.类变量名 = 变量值
不允许使用 对象名.类变量名 = 变量名修改 这样会给该变声明一个独有属性 仅修改该对象的属性值
类变量可以私有化
作用:记录创建了多少个对象 +=1
记录一个总数 每个方法都能调用 且通用
2.类方法
定义格式:
在类方法中,类属性访问可以通过 cls.类属性名
来访问
class 类名: @classmethod def 方法名(cls, 形参): 方法体复制代码
调用格式:
类名.方法名(实参) (推荐) 对象名.方法名(实参) (不推荐)
如果类方法和成员方法名字冲突时,不能使用 对象名.方法名(实参) 调用方法,这样会调用写在后面的方法,
通过cls(变量名)可以创建一个对象
只要方法名称相同(无论修饰符是否一样) 就会出现覆盖的情况 后面写的会被调用
注意:类方法和成员方法之间的相互调用
类方法中不允许使用实例变量和实例方法
实例方法中允许使用类变量和类方法,推荐使用类名调用
class Dog: var = "都是狗" #类变量 定义在类里 def __init__(self, name, age): # 对象变量 定义在init里 self.name = name self.age = age @classmethod # 定义一个类方法 def show_me(cls): print("类方法的狗子") # slef.show 成员方法无法调用类方法和类变量 def show(self): # 定义一个成员方法 print(Dog.var) # 类方法可以定义成员变量 Dog.show_me() #类方法可以调用成员方法 print("成员方法的狗子")dog1 = Dog("狗子", 18)dog1.var = "不是狗"print(dog1.var)dog1.show()复制代码
-
注意:self 和cls的自动补充:
这只是一个变量名而已,自动补充的 可以用任何变量名代替
-
静态方法(了解 不常用)
@staticmethod # 静态方法的创建def show1(): print("一个静态方法")复制代码
调用方法:
类名.方法名(实参) (推荐)
对象名.方法名(实参) (不推荐)
静态方法的定义与类无关,与对象无关,可以转化成函数定义
用途:用于存放工具类,使其存放在一起,类名.即可看到
3.面向对象名称的总结
- 公有变量:类中 有self.前缀的变量都是公有变量
- 全局变量:在文件的最外层,或者在函数中加了global的变量
- 局部变量:定义在函数中的,类中的方法里,成员变量名没有self的也是局部变量
- 独有变量:只有这一个对象才有的变量,
- 私有变量:类变量名前有2个下划线__的称为私有变量,只能在类的内部使用
- 类变量:定义在类的下边,没有在方法里面
- 成员变量 = 公有变量
- ______init__方法:构造方法
- 对象 可以称为实例
5.2继承
1.基础格式:
class 子类名称(父类名称):
pass
继承描述的是一种类间关系,一个类从另一个类获取成员信息的类间关系。
继承作用:继承父类的变量和方法;子类可以添加父类没有的东西,父类私有成员不可以被继承
2.继承的关系结构图
- object是所有类的父类
查看继承关系结构:类名.mro
class Anmail: passclass Cat(Anmail): #Anmail是cat的父类 passclass SmallCat(Cat): # Cat是smallcat的父类 passprint(SmallCat.__mro__)# 此时输出:(, , , )# 即 object是Anmail的父类,Anmail是Cat的父类,Cat是SmallCat的父类复制代码
3.重写
子类重写了__init__
时,实例化子类,就不会调用父类已经定义的__init__
,即被重写
- 在子类中可以定义与父类相同名称的方法,此时子类的方法对父类的方法构成了重写。 如果子类重写了父类的方法,使用子类对象调用被重写的方法时,执行子类中重写后的方法
__str__方法就是一个重写
调用父类被重写的方法:
1 父类名.init(self,参数)#注意名字是父类
2 super(子类名,self).init(参数)#注意名字是子类,而且init后是se1f之外的参数
调用格式一:父类名.方法名(对象)
调用格式二:super(本类名,对象).方法名()
调用格式三:super().方法名() (推荐)
重写后 父类和子类的信息都会有 而不是覆盖
class People: def __init__(self, age): self.name = None self.age = age def said(self): print("父类说")class Man(People): def __init__(self): super().__init__(None) # 子类重写时如何调用父类的成员变量? 参数不能写变量吗? self.sex = "man" def said(self): print("子类说") super().said()people1 = People(18)print(people1.age)man1 = Man()print(man1.age)复制代码
init方法中,子类要重新父类init时,父类传递了参数,子类也需要传参
class Person(): def __init__(self,name,age): self.name = name self.age = ageclass Teacher(Person): def __init__(self,name,age): 父类有 super().__init__(name,age) self.id = "111"复制代码
4.多继承
格式: class 子类名(父类名1,父类名2,父类名3):
pass
如果方法,变量有冲突,则先选择写在前面的父类
重写:父类名.方法名(self)
如果写super().方法名(),则默认调用写在前面的父类名方法(父类名1)
需要查看具体重写的那个方法 同样用:类名.___ __mro _
5.多态
同一个对象,在不同的使用环境中以不同的形态展示其功能,称该对象具有多态特征
多态发生在继承关系的基础之上
# 同一个对象,在不同的使用环境中以不同的形态展示其功能,称该对象具有多态特征。class Eat: def breakfast(self): print("吃饭")class Sleep: def bed(self): print("睡觉")class Man(Eat,Sleep): def breakfast(self): print("吃早饭呢") def bed(self): print("在床上睡觉")class Demo: def test(self,who): who.breakfast()eat1 = Eat()man1 =Man() # 以多态的形式展现出来 需要eat 但是给了一个具有eat方法的子对象也行demo1 = Demo()demo1.test(man1)复制代码
鸭子类型
对象在语法层面满足调用关系,实际不具有对应的对象形态,称该对象此时具备鸭子类型
鸭子类型是一种特殊的多态表现形式 鸭子类型和多态就差了一个继承
class Eat: def rice(self): print("吃米饭")class Paly: def player(self): print("玩游戏")class Man(Eat,Paly): # 子类 def rice(self): print("吃好吃的米饭") def player(self): print("玩好玩的游戏")class Stdent: # 没有关系的类 def rice(self): print("学生也不吃饭") def play(self): print("好学生不玩游戏")class Demo: def demo1(self,who): who.rice()demo = Demo()man =Man()std1 = Stdent()demo.demo1(man) # 继承demo.demo1(std1) # 鸭子类型(没有继承)复制代码