day29 Pyhton 面向对象 多态 封装

# coding:utf-8
# py2中的经典类
# class D:#没有继承object是经典类
#
pass # # def func(self): # # print('d') # class B(D): # pass # # def func(self): # # print('b') # class C(D): # pass # def func(self): # print('c') # class A(B,C): # pass # # def func(self): # # print('a') # a = A() # a.func() # python2.x中的经典类 # 多继承中深度优先 # 没有mro提示你顺序 # 没有super # python2中的新式类 基本和python3中的新式类相似 class D(object):#继承了object是新式类
pass # def func(self): # print('d') class B(D): pass # def func(self): # print('b') class C(D): pass def func(self): super(C,self).func() print('c') class A(B,C): pass # def func(self): # print('a') a = A() a.func() print(A.mro()) # 方法 print(A.__mro__) # 属性
# python2.x版本中存在两种类
# 经典类
    # 不主动继承object类的所有类都是经典类
    # 继承关系遵循深度优先算法
    # 没有mro,没有super
# 新式类
    # 所有继承object类的都是新式类
    # 和py3一样继承遵循mro顺序和c3算法
    # 有mro方法,但是super的使用必须传参数super(子类名,对象名).方法名

# python3.x中的类和py2.x中的新式类有什么区别???
    # 不需要主动继承object
    # py3中super()可以直接用,py2中使用必须传参数super(子类名,对象名).方法名

# 所有继承了object类的都是新式类 <==> 所有的新式类都继承object类
# PEP8规范 : 跨环境 无论在py2还是py3中定义一个新式类,都需要加上object这个继承
# class 类名(object):
#     pass
# class 子类(类名):
#     pass
# python中处处是多态 # python是一门自带多态的语言
# java 的多态
# 强数据类型的语言
# def pay(float money):  # float 2.35 - 类 对象
#     print(money)
# pay()

# class Payment(object):pass
# class Alipay(Payment):
#     def pay(self,money):
#         pass
# class Wechatpay(Payment):
#     def pay(self,money):
#         pass
# def pay(Payment person_obj,float money):
#     person_obj.pay(money)
# alex = Alipay()
# pay(alex,24.5)
# yuan = Wechatpay()
# print(yuan,23.5)
# 一个类表现出来的多种状态
# 支付Payment是一个类,多种状态: 使用阿里支付Alipay,使用微信支付Wechatpay
# 支付表现出来的多种状态 :
    # 第一种状态 支付宝支付
    # 第二种状态 微信支付
# class Animal(object):pass
# class Cat(Animal):
#     def eat(self):pass
# class Dog(Animal):
#     def eat(self):pass
# def eat(Animal obj):
#     obj.eat()
# 小花 = Cat()  # 小花就是猫类的对象 类==类型==数据类型,小花的类型就是Cat
# 小黑 = Dog()
# eat(小花)
# eat(小黑)
# int str list tuple dict set 内置的数据类型
# Cat Dog Animal 自定义的类/数据类型
# 动物吃表现出来的多种状态:
    # 猫吃
    # 狗吃
# python
# class Cat(object):
#     def eat(self):pass
# class Dog(object):
#     def eat(self):pass
# def eat(obj):
#     obj.eat()
# 小花 = Cat()  # 小花就是猫类的对象 类==类型==数据类型,小花的类型就是Cat
# 小黑 = Dog()
# eat(小花)
# eat(小黑)
# 动物吃表现出来的多种状态:
    # 猫吃
    # 狗吃

 

# class Alipay(object):
#     def pay(self,money):
#         pass
# class Wechatpay(object):
#     def pay(self,money):
#         pass
# def pay(person_obj,money):
#     person_obj.pay(money)
# alex = Alipay()
# pay(alex,24.5)
# yuan = Wechatpay()
# print(yuan,23.5)
# pay('abc',23.5)#错误,无法判断输入的数据类型是否正确
# 在python中体现的多态:     
  # 几个类拥有同名的方法,可以写一个函数,来统一进行调用 - 归一化设计
# java要要求传递数据的数据类型? (通过继承来实现的)
  # 是为了代码不出错,只要你能够顺利的调用这个函数,那么内部的执行就大大降低出错的概率
# python却不要求?
  # 更多的不是硬性的规定,但是可能会因为传递的参数不符合规则而使得代码报错,但是大大降低了代码繁琐程度
# 鸭子类型 
# 是python语言中特有的,不依赖于继承和规范来进行的一种约定(依赖继承和规范特指:java中的多态和接口)
# 如果两个类都需要做某一件事情,那么应该起相同的名字,这个时候,对于做的这件事情来说,这两个类就变成了鸭子类(归一化设计的表现)

# 中心思想 : 不同类之间的相同的方法都应该用同一个名字  
# 抽象类 规范 : 不同类之间的相同的方法都应该用同一个名字
# 接口类 规范: 不同类之间的相同的方法都应该用同
一个名字
# class Animal:pass
# class Cat(Animal):
#     def eat(self):pass
# class Dog(Animal):
#     def eat(self):pass
# def eat(Animal obj):
#     obj.eat()
# 多态      : 已经实现了"不同类之间的相同的方法都用同一个名字",解决不同类的对象的传参问题

class Cat:
    def eat(self):pass
class Dog:
    def eat(self):pass
def eat(obj):
    obj.eat()
# 鸭子类型  : 不需要解决类的对象的传参问题,就可以直接利用已经实现的"不同类之间的相同的方法都用同一个名字"
# 什么是封装?     
  # 广义上(大家认为的) :
    # 把一类事务的相同的行为和属性归到一个类中
# class Dog:
# def bite(self):pass
    # 狭义上(学术上的定论) :
      # 把一些特殊的属性和方法藏在类中
      # 外部无法调用,只有内部可以调用
# 隐藏静态属性
class Dog:
    # dog_sum = 0         # 不安全,因为这个属性可以在类的外部被随便修改
    __dog_sum = 0         # 安全,通过dog_sum方法和__变量名让属性变成只能看不能改的值
    def __init__(self):
        self.count()
    def count(self):
        Dog.__dog_sum += 1 # 可以从一个类的内部使用__dog_sum的属性
    def dog_sum(self):
        return Dog.__dog_sum

print(Dog.__dict__)
alex = Dog()
print(Dog.__dict__)
# print(Dog.__dog_sum)    # 不可以从外部直接使用这个变量
print(alex.dog_sum())

class Dog:
    __dog_sum = 0       # 私有的静态属性 _Dog__dog_sum
    def __init__(self):
        self.count()
    def dog_sum(self):
        return Dog.__dog_sum # 只要是在类的内部使用__名字,默认就被改成 _类名__名字

print(Dog.__dict__)
print(Dog._Dog__dog_sum)     # 绝不能在后续我们的代码中出现这种情况,这是bug不能用
#
只要是在类的内部的名字前面加上双下划线 # 那么这个名字 就变成 私有的 (只能在类的内部使用,不能在类的外部使用) # 在定义的时候,存储的名字就会发生变化 _类名__名字 # 因此 在类的外部就不会被调用到了 # 在类的内部 使用__名字,默认就被改成 _类名__名字

# class Dog:
#     def __init__(self,name,password):
#         self.__name = name           # 不希望某个值被随便修改
#         self.__password = password   # 不希望某个值被从类的外部看到
#     def login(self,usr,pwd):
#         if usr == self.name and pwd == self.__password:
#             return True
#     def name(self):
#         return self.__name
#     def set_name(self,new_name):
#         if type(new_name) is str:
#             self.__name = new_name
#
# alex = Dog('alex','sb123')
# print(alex.login('alex','sb222'))
# print(alex.login('alex','sb123'))
#
# print(alex.name())
# alex.set_name('alex_sb')
# print(alex.name())

# 只能在类的内部被调用,保证了类内部数据的安全,不会被别人随意修改
# 私有静态属性  : 为了不随意被外部修改
# 私有方法     :  不希望被外部随意调用
# 私有的对象属性 :
    #  不希望某个值被随便修改
    # 不希望某个值被从类的外部看到

# 私有的名字能不能被子类继承?为什么?

 


 


 


 



 

 
posted @ 2018-11-23 17:51  Python张梦书  阅读(228)  评论(0编辑  收藏  举报