1、成员方法调用成员变量:
成员方法调用成员变量:
-
类模板里面的 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、成员方法调用成员方法:
class Man:
# 成员方法
def sing(self):
print('唱了一支歌')
def dance(self):
print('跳了一支舞')
def run(self):
# 调用成员方法
self.sing()
self.dance()
man1 = Man()
man1.run() # 调用简单
3、封装、私有化:
面向对象的三大特点:
- 封装(第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.__变量名 = 形参
封装操作可以对受保护的成员进行功能开放的控制,达到保护数据不被非法访问的目的
方法也可以私有、封装,但是一般用不到
4、类变量:(不会随着对象的改变而发生改变)
实例变量 >> 会随着对象的变化而发生改变
成员变量、成员方法:
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)
5、类方法:(不会随着对象的改变而发生改变 )
实例方法 >> 会随着对象的变化而发生改变
# 定义格式
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()
6、类方法注意事项:
- 1、类方法 中不允许使用 实例变量 和 实例方法
- 2、实例方法 中允许使用 类变量 和 类方法。
类方法中不允许调用实例变量和方法:
但是,下面用 对象名.实例变量 就可以调用,原因是 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()
7、静态方法:(就是一个被打包在类模板里面的函数)
就是说,现在有一个类模板,有一个函数,你不想让这两者分开,想让它们组合在一起,让代码块更好地捆绑在一起,这就是静态方法的意义
# 定义格式:
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() # 对象名.方法名(实参)
8、继承:
继承是一种类间关系,描述一个类从另一个类获取成员信息的类间关系
继承必定发生在两个类之间,参与继承关系的双方成为 父类 和 子类;父类 提供成员信息,子类 获取成员信息
# 定义格式:
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()
9、继承关系:
object类 是所有类的共同的父类,又叫 基类
查看继承关系:
class father:
pass
class son(father):
pass
class sun(son):
pass
print(sun.__mro__)
10、重写、继承重写:
重写:
在子类中如果定义了和父类相同名称的方法,那么此时的子类的方法就对父类的方法构成了 重写
如果子类重写了父类的方法,使用子类对象调用被重写的方法时,执行子类中重写后的方法
儿子有的,就用儿子自己的,没有再去找爸爸要!
class father:
def play(self):
print('去湖边钓鱼')
class son(father):
def play(self):
print('去球场打球')
s = son()
s.play()
继承重写:
在子类中调用父类中被重写的实例方法:
# 调用格式一:
父类名.方法名(对象)
# 调用格式二:
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种格式,前面两种格式相对比较繁琐
11、多继承的关系:
# 定义格式:
class son(father1,father2,father3,...)
pass
class father1:
def sing(self):
print('会唱歌')
class father2:
def dance(self):
print('会跳舞')
class father3:
def play(self):
print('会打篮球')
class son(father1,father2,father3):
pass
s = son()
s.sing()
s.dance()
s.play()
有个问题,继承几个父类的顺序是什么样的呢?
继承的优先级是:father1 > father2 > father3 > object
就近原则继承
只有继承关系,是它们真正寻找的路径,其它都是虚的
12、多态的概念:
一个对象具有多种形态,在不同的使用环境中,以不同的形态展示其功能,那么我们就称该对象具有多态特征。
多态发生在具有继承关系的基础上
比如说:水! 有 固态、液态、气态,但是最原始的组成还是 H2O
son1 | son(1,2,3,4) |
---|---|
开车 | 司机 |
唱歌 | 歌手 |
做饭 | 厨师 |
打球 | 教练 |