成员方法调用成员变量:
类模板里面的 init 方法当中定义的公有变量
在创建对象出来之后定义的独有变量
公有变量:可以访问,通过 self.变量名调用 独有变量:谨慎操作 class Man: # 成员变量的定义 def __init__(self): # 对象本身 self.gender = '男性' self.name = None # 成员方法 def myself(self): # 成员方法去调用成员变量(公有变量) print('我是:%s,性别是:%s' %(self.name,self.gender)) man1 = Man() man1.name = '小王' man1.myself()面向对象的三大特点:
封装(第2)继承(第1)多态(第3)私有属性 / 成员变量
class Man: # 成员变量 / 属性 def __init__(self): self.id_card = None man1 = Man() print(man1.id_card)私有化了,外部访问不到:
对成员私有化可以有效的保护从类的外部对内部成员进行访问
# 私有属性定义格式: self.__变量名 = 值 # 私有方法定义格式: def __方法名(self): 方法体但是,类的外部拿不到私有属性,但是类的内部是可以间接拿到私有属性的
class Man: # 成员变量 / 属性 def __init__(self): self.__id_card = None def get_id_card(self): return self.__id_card man1 = Man() print(man1.get_id_card())通过成员方法去间接的拿到私有属性
通过一个间接的方式去修改、设置私有属性、变量:
class Man: # 成员变量 / 属性 def __init__(self): self.__id_card = None def get_id_card(self): return self.__id_card def set_id_card(self,id_card): self.__id_card = id_card man1 = Man() # 外部去给id_card传具体的值,参数的传递 man1.set_id_card('430********') # 通过成员方法去间接的拿到私有变量/属性 id_card = man1.get_id_card() print(id_card)这个 先设置,再得到 的过程,就叫 封装,封装就是对某些特定的东西,进行私有化,让外部不能容易得到
封装定义格式:
# 1、对成员变量进行私有设置: self.__变量名 = 值 # 2、提供对外访问器: 访问器(get方法): def get_变量名(self): return self.__变量名 修改器(set方法): def set_变量名(self,形参): self.__变量名 = 形参封装操作可以对受保护的成员进行功能开放的控制,达到保护数据不被非法访问的目的
方法也可以私有、封装,但是一般用不到
实例变量 >> 会随着对象的变化而发生改变
成员变量、成员方法:
class Man: # 成员变量的定义 self代表的是对象本身 创建对象之后去执行 def __init__(self,name,sex,height): # 对象本身 self.name = name self.sex = sex self.height = height # 成员(实例)方法 def somebody(self): # 成员方法去调用成员变量(公有变量) print('我是%s,%s,身高是%s'%(self.name,self.sex,self.height)) man1 = Man('姚明','男','200cm') # 传参 init方法的调用 man1.somebody() man2 = Man('科比','男','198cm') man2.somebody()类变量:
类中的成员变量描述对象的属性根据对象不同,会产生区别,称此类变量为 实例变量类中的成员变量描述对象的属性值根据对象不同,不会产生区别,称此类变量为 类变量类变量是归属类的,实例变量是归属对象的
# 定义格式: class 类名: 变量名 = 值 # 调用格式: 赋值: 类名.变量名 = 值 取值: 类名.变量名 对象名.变量名(不常用) class Man: # 类变量 > 不会随着对象的改变而发生改变 country = '中华人民共和国' # (成员)实例变量 def __init__(self,name,gender): self.name = name self.gender = gender # (成员)实例方法 > 随着对象的改变而发生改变 def somebody(self): print('我是:%s,我是一个:%s,我为中国加油'%(self.name,self.gender)) man1 = Man('张三','男') # 创建对象,意味着init方法被自动调用 # 调用类变量 1、类名.变量名 2、对象名.变量名(不推荐) print(Man.country) print(man1.country) # 不推荐! Man.country = '中国' # 修改类变量 man2 = Man('李四','男') print(Man.country)实例方法 >> 会随着对象的变化而发生改变
# 定义格式 class 类名: @classmethod def 方法名(cls,形参): 方法体 # 调用格式: 类名.方法名(实参) 对象名.方法名(实参) # 不常用 class Man: # 类变量 > 不会随着对象的改变而发生改变 country = '中华人民共和国' # (成员)实例变量 def __init__(self,name,gender): self.name = name self.gender = gender # (成员)实例方法 > 随着对象的改变而发生改变 def somebody(self): print('我是:%s,我是一个:%s,我为中国加油'%(self.name,self.gender)) @classmethod def fighting(cls): print('我是中国人,我骄傲!') man1 = Man('张三','男') Man.fighting() man1.fighting()类方法中不允许调用实例变量和方法:
但是,下面用 对象名.实例变量 就可以调用,原因是 self 是单单指的是本实例
实例方法调用 类变量、类方法:
class man: people = '中国' def __init__(self,name,sex): self.name = name self.sex = sex def somebody(self): print('我是:%s,性别是:%s' %(self.name,self.sex)) print(man.people) man.go() @classmethod def go(cls): print('加油!') m = man('张三','男') m.somebody()就是说,现在有一个类模板,有一个函数,你不想让这两者分开,想让它们组合在一起,让代码块更好地捆绑在一起,这就是静态方法的意义
# 定义格式: class 类名: @staticmethod def 方法名(形参): 方法体 # 调用格式: 类名.方法名(实参) 对象名.方法名(实参) class a: def __init__(self,name,age): self.name = name self.age = age @staticmethod # 固定的语法格式,把下面的函数(方法)变成静态方法 def say(): print('真厉害!') b = a('张三','男') a.say() # 类名.方法名(实参) b.say() # 对象名.方法名(实参)继承是一种类间关系,描述一个类从另一个类获取成员信息的类间关系
继承必定发生在两个类之间,参与继承关系的双方成为 父类 和 子类;父类 提供成员信息,子类 获取成员信息
# 定义格式: class 类名(父类名): pass继承父类的成员:
变量方法子类可以添加父类没有的成员;父类私有成员不可被继承
# 看看实例变量的能否继承使用 class father: # 实例变量 def __init__(self): self.name = None self.sex = None class son(father): # 产生继承关系 pass s = son() s.name = '王小明' s.sex = '男' print(s.name,s.sex) # 看看方法可不可以被继承使用 class father: def say(self): print('说话') def dance(self): print('跳舞') class son(father): pass s = son() s.say() s.dance()object类 是所有类的共同的父类,又叫 基类
查看继承关系:
class father: pass class son(father): pass class sun(son): pass print(sun.__mro__)重写: 在子类中如果定义了和父类相同名称的方法,那么此时的子类的方法就对父类的方法构成了 重写
如果子类重写了父类的方法,使用子类对象调用被重写的方法时,执行子类中重写后的方法
继承重写:
在子类中调用父类中被重写的实例方法:
# 调用格式一: 父类名.方法名(对象) # 调用格式二: super(子类名,对象).方法名() # 调用格式三: super().方法名() class father: def play(self): print('去湖边钓鱼') class son(father): def play(self): print('去球场打球') # 格式一:父类名.方法名(对象) father.play(self) # 格式二:super(子类名,对象).方法名() super(son, self).play() # 格式三:super().方法名() super().play() s = son() s.play()一般只用第3种格式,前面两种格式相对比较繁琐
有个问题,继承几个父类的顺序是什么样的呢?
继承的优先级是:father1 > father2 > father3 > object
就近原则继承
只有继承关系,是它们真正寻找的路径,其它都是虚的
一个对象具有多种形态,在不同的使用环境中,以不同的形态展示其功能,那么我们就称该对象具有多态特征。
多态发生在具有继承关系的基础上
比如说:水! 有 固态、液态、气态,但是最原始的组成还是 H2O
son1son(1,2,3,4)开车司机唱歌歌手做饭厨师打球教练