面向对象的三大特性:封装,继承,多态

面向对象的三大特性:封装,继承,多态

封装分类:     私有化封装(只允许在内部访问)

       公共的封装(内外部都可以访问)

       受保护的封装

#私有化封装:只允许在内部访问
#改名策略的格式为:_类名__属性名 _类名方法名__

# class Man:
# name='男人'
# __sex='男'
# def run(self):
# print(self.__sex)
# print('跑起来速度很快')
#
# def __swim(self):
# print('游泳对身体很好哟')

# nr=Man()
# print(nr.__sex) 在外部访问不了,会报错
# nr.run() #只能在内部访问

#利用改名策略来访问私有化封装(不允许访问,这关系到程序员的职业道德素养问题)
# print(nr._Man__sex)
# nr._Man__swim()

# 公共封装 :内外部都能访问 (即写个类就好)
class Man:
name='男人'
sex='男'
def run(self):
print('跑的好快啊')

#受保护的封装:在继承中出现,允许内外部访问,效果和公共的封装一样

在属性名/成员方法名前加‘_’即可

class Human:
eye=2
_legs=2
def think(self):
print('人类会思考')

def use(self):
print('人类会使用工具')

class Blace_Man(Human):
pass

berte=Blace_Man()
print(berte._legs)
berte.use()

继承相关的概念:被继承的类叫父类/基类/超类
        继承其他类的类叫做:子类/派生类
继承的意义:
提高代码的重用率
建立新的类与类的关系
方便其他逻辑操作

继承格式:
class 父类(object):
  pass
class 子类(父类):
  pass

继承的特征:
在不指定父类的情况下,所有的类均继承自己的object类(系统提供的)
2.子类继承父类就是具有父类的所有成员
3.子类继承父类,不会将父类成员复制到子类当中,子类如果需要成员,可以找父类索取
4.私有化的成员,允许在子类中单独建立一份,不会找父类索取似有成员
5.子类可以根据需求添加自己独有的成员来进行操作
6.子类重载父类的成员属性时,仅仅是对子类/对象有效,并不会影响父类
7.子类在重载父类的方法时,也可以调用父类的方法进行操作
   方法一:父类名。父类方法名(参数)----不推荐使用
   方法二:super()。父类名()
class Human:
eye=2
__legs=2
def think(self):
print('人类会思考')

def use(self):
print('人类会使用工具')

class Blace_Man(Human):
eye = 3
def think(self):
print('黑人也会思考的')
#调用父类的方法进行操作
# 方法一:父类名.父类方法(随便写个参数)不推荐使用
Human.think(1)
#方法二:super().父类方法名() 推荐使用
super().think()

berte=Blace_Man()
# print(Blace_Man.__dict__)
#私有化成员当中,允许在子类中单独建立一份,不会找父类索取私有成员
# print(berte._Blace_Man__legs) #会报错
#子类重载父类的成员,仅仅是对子类/对象有效,并不会影响父类
# print(berte.eye)
#子类在重载父类的方法时候,也可以调用父类的方法进行操作
berte.think()

继承:
单继承:一个类只能继承一个父类的方式
多继承:一个类可以继承多个父类的方式
单继承:
# class Human:
# eye=2
# def run(self):
# print('人类用两条腿跑步')

# class Man(Human):
# hair='短发居多'
# def money(self):
# print('男人会挣钱')
#
# class Child(Man):
# pifu='又白又嫩'
# def ku(self):
# print('哭的声音很大')
#
# baby=Child()
# print(baby.eye)
# print(baby.hair)
# baby.run()

多继承:
class Human:
eye=2
def run(self):
print('人类用两条腿跑步')

class Man():
hair='短发居多'
def money(self):
print('男人会挣钱')

class Woman():
hair='长发飘飘'
def work(self):
print('女人也会工作')

class Child(Human,Woman,Man):
pifu='又白又嫩'
def ku(self):
print('哭的声音很大')

baby=Child()
baby.ku()
baby.work()
print(baby.eye)
print(baby.hair) #是根据继承类的顺序输出的

多继承的缺点:菱形bug中某个办法在继承中多次被调用
解决办法:用super().父类名()
当我们定义一个菱形时会自动生成一个MRO列表
MRO列表生成原则:1.子类永远在父类的前面
         2.同一等级的类,按照子类中的继承顺序摆放
查看mro列表的方法
print(类名.mro()) 或者 print(类名.__mro__)
super()调用时,不是查找类,实际上super是查找MRO列表上的一个类
super()调用对象时不用传入对象,自动传入
class Human():
def think(self):
print('人类会思考')

class Man(Human):
def think(self):
super().think()
print('男人思考如何赚钱')

class Woman(Human):
def think(self):
super().think()
print('女人思考如何让男人赚钱')

class Child(Man,Woman):
def think(self):
super().think()
print('小孩思考吃喝玩乐')

baby=Child()
baby.think()
print(Child.mro())

issubclass(子类,父类):检测是否是子类
res=issubclass(Child,Man)
print(res) #TRUE
res=issubclass(Man,Woman)
print(res) #FALSE
res=issubclass(Child,Human)
print(res) #TRUE
多态:
定义:不同的子类对象调用相同的父类方法,产生不同的执行结果
多态指的是一类事物有多种形态(一个抽象类有多个子类,因而多态的概念依赖于继承)
多态是调用方法的技巧,不会影响到类的内部设计
关键点:继承,重载
class Human():
def think(self):
print('人类会思考')

class Man(Human):
def think(self):
print('男人思考如何赚钱')
def action(self):
print('男人为赚钱而努力')

class Woman(Human):
def think(self):
print('女人思考如何变美')
def action(self):
print('女人为变美去化妆')

class RenYao(Human):
def think(self):
print('人妖思考如何长寿')
def action(self):
print('为了长寿上台表演')

man=Man()
woman=Woman()
renyao=RenYao()

#利用多态做一个小实例
list1=[man,woman,renyao]
while True:
res=input('请输入指令:1.全体行动 2.全体思考 3.人妖思考,其余人行动 其他指令退出行动')
for name in list1:
if res=='1':
name.action()

elif res=='2':
name.think()

elif res=='3':
if name==renyao:
name.think()
else:
name.action()
else:
exit()