python基础-day21

转载 2018年04月16日 20:21:47
# 再来谈谈多继承的,继承原则,
# 当一个节点可以在深度广度上都有机会被访问到的时候,优先从广度上查找
# 这几句话也间接的说明了,那个节点,有两条路可以被访问,
# 而优先从广度上查找,意思就是后面找得到的,暂时就不找了,
# 
# 
# 对于一些难懂的代码,翻译层中文帮助理解,
# 
# 
# 要总结,因为这个可以帮你把以天为单位存储的知识,
# 融合为一个整体,因为在真正使用的时候,你不知道你会用到哪个知识点,
# 


# len()  和 __len__()
# 只有一个类中实现了__len__()方法,才能使用len()函数
# def len2(obj):  # 归一化设计
#     return obj.__len__()

# 归一化设计,就是说,
# 列表,集合,元组等,都能通过len()这一个方法获取长度,
# 是因为这些类型的数据,在其类的内部,都实现了同一个接口,即__len__()方法,

l = [1,2,3]
print(len(l))   #打印结果为:3
print(l.__len__())      #打印结果为:3
print('__len__' in list.__dict__)   #打印结果:True,说明list类里面实现了__len__方法,


# 创建一个规范
from abc import ABCMeta,abstractmethod   #!!!python中的抽象类,需要借助于这个模块来实现,
class Payment(metaclass=ABCMeta):     #抽象类 接口类  规范和约束  metaclass指定的是一个元类,说明这个类是抽象类(或者说是接口类)
                                      #无论是抽象类还是接口类metaclass=ABCMeta之后,都代表这个类不可以被实例化
    s = 'haha'
    @abstractmethod                     #被abstractmethod修饰之后,子类就继承了这个方法,子类需要去实现,如果子类也打算当抽象类,我还没试过,
                                        # 打印子类的__dict__,里面会有 '__abstractmethods__': frozenset({'pay'}),键的意思是抽象方法,此时子类也是抽象类了,
                                        #故如果子类不实现继承来的抽象方法,就无法实例化,
                                        # 通过type查看抽象类,会打印:<class 'abc.ABCMeta'>,即抽象类,
                                        #有些时候,与其说抽象类方法不实现,还不如说是子类已经继承,如果不实现子类就无法实例化,
                                        # 而实现继承来的方法,首先就调用的是子类自己实现的方法,
    def pay(self):
        print(Payment.s)
        pass  # 抽象方法

class Alipay(Payment):
    pass
    def pay(self,money):
        pass
        # print(Payment.pay(money))
        # print('使用支付宝支付了%s元'%money)

class QQpay(Payment):
    def pay(self,money):
        print('使用qq支付了%s元'%money)

class Wechatpay(Payment):
    def pay(self,money):
        print('使用微信支付了%s元'%money)
    def recharge(self):pass

def pay(a,money):
    a.pay(money)

a = Alipay()
a.pay(100)
print(Alipay.__dict__)
print(type(Alipay)) #<class 'abc.ABCMeta'>,即抽象类,
print(type(Payment))    #<class 'abc.ABCMeta'>


# 下面这么多看起来差不多的调用方法,是想说,归一化设计之后,不同类可以使用相同的函数去调用
a = Alipay()
a.pay(100)
pay(a,100)    # 归一化设计:不管是哪一个类的对象,都调用同一个函数去完成相似的功能
q = QQpay()
q.pay(100)
pay(q,100)
w = Wechatpay()
pay(w,100)   # 如果把Wechatpay类的pay方法名改为fukuan,这里就会报错,所以目前这种情况是不会报错的,

# ps:
#关于子类得实现继承自抽象类的方法,这个实现是说,你必须def,但是里面的内容可以是pass语句,
#抽象类的本质还是类,指的是一组类的相似性,包括数据属性(如all_type)和函数属性(如read、write),而接口只强调函数属性的相似性。


# 抽象类和接口类
# java 编程原则和设计模式
# 设计模式  程序设计 具有里程碑意义的设计方式 从java中演变出来的
# 单例模式是一种设计模式,即一个类只有一个实例
## 算法导论  计算的方法 时间和空间的问题 权威通用

#java不能多继承

# 编程原则
    # python
    # 开放封闭原则
        # 开放 对扩展是开放的
        # 封闭 对修改是封闭的
    # 依赖倒置原则
    # 接口隔离原则
# 已经写完的程序代码是不允许修改的


# 依赖倒置原则:!!!!!!!
# 高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该应该依赖细节;细节应该依赖抽象。换言之,要针对接口编程,而不是针对实现编程


# 1,在继承抽象类的过程中,我们应该尽量避免多继承,
# 2,而在继承接口的时候,我们反而鼓励你来多继承接口,
#头一句好理解,抽象使得我们的结构变的复杂,用前面讲多继承时候的话来说,就是给自己挖坑
#而第二句,可能是由于一个继承于多个,而且继承的目的是为了统一实现,所以推荐吧,还有待深入思考


# 1,在抽象类中,我们可以对一些抽象方法做出基础实现
# 2,而在接口类中,任何方法都只是一种规范,具体的功能需要子类实现
# 关于抽象类方法的实现与否,我觉得更多是一种建议,编译器并没有强制要求你不能写,
# 因为在编译器的角度来说,你只要有def,哪怕函数实现是pass,编译器好像也认为你实现了,
# 其次,子类继承抽象类,子类如果不实现父类的方法,就无法实例化,实现了之后,就首先调用的是自己的方法,
# 所以从多个侧面来分析,外加我们最初定义抽象类就不是想要在抽象类中实现什么方法,
# 所以可以理解为抽象类中可以做出一些基础实现,而接口中并不实现,
# 最上面两句的规定,我个人理解,更多是出于一种建议.


#!!!!!感觉下面接口的列子和总结,都很简洁,就没必要自己修改了,直接用了,
# 什么叫接口
# python里没有接口的概念
# 那接口是哪儿来的概念呢?
    # java类没有多继承 接口可以实现多继承
# 描述动物园
# 会游泳的 会走路的 会爬树的 会飞的
# 老虎
# 青蛙
# 天鹅
# 猴子
from abc import ABCMeta,abstractmethod
class FlyAnimal(metaclass=ABCMeta):
    @abstractmethod
    def fly(self):pass
    @abstractmethod
    def cal_flying_speed(self):pass
    @abstractmethod
    def cal_flying_height(self):pass
class WalkAnimal(metaclass=ABCMeta):
    @abstractmethod
    def walk(self):pass
class SwimAnimal(metaclass=ABCMeta):
    @abstractmethod
    def walk(self):pass
class Tiger(WalkAnimal,SwimAnimal):
    def walk(self):pass
    def swim(self):pass
class Monkey:
    def walk(self):pass
    def climb(self):pass
class Swan(FlyAnimal,WalkAnimal,SwimAnimal):
    def swim(self):pass
    def walk(self):pass
    def fly(self):pass
    def cal_flying_speed(self):pass
    def cal_flying_height(self):pass
class Parrot(FlyAnimal):
    def fly(self):pass
    def cal_flying_speed(self):pass
    def cal_flying_height(self): pass
# 所有会飞的动物 具有一些会飞的动物的特性
# 所有会走的动物 具有一些会走的动物的特性

# 接口类的作用:
    # 在java中,能够满足接口隔离原则,且完成多继承的约束
    # 而在python中,满足接口隔离原则,由于python本身支持多继承,所以就不需要接口的概念了

# 抽象类和接口类
# 在python中
    #并没有什么不同,都是用来约束子类中的方法的
    #只要是抽象类和接口类中被abstractmethod装饰的方法,都需要被子类实现
    #需要注意的是,当多个类之间有相同的功能也有不同的功能的时候,应该采用多个接口类来进行分别的约束

# 在java中
    # 抽象类和接口截然不同
    # 抽象类的本质还是一个类 是类就必须遵循单继承的规则,所以一个子类如果被抽象类约束,那么它只能被一个父类控制
    # 当多个类之间有相同的功能也有不同的功能的时候 java只能用接口来解决问题

# 面试的时候
    # 抽象类 是python中定义类的一种规范
    # 接口,ps:!!!!!!!!我自己补充的,接口就是java为我们提供的一种机制,帮助我们解决,多个类之间有相同的功能,也有不同的功能,
# 在公司类写代码的时候
    # 如果遇到抽象类 记得按照抽象类中的规范一一实现对应的方法,ps:我自己补充点,简单说,项目中以别人的规范作为参考来写,


# 接口是为了规范写法,特别是多人编程的情况下,显得非常重要,
# 而如果就你一个人,用不用接口来规范编写,就不是那么重要了,

#关于多态,ps:我自己来个解释,同样的调用方式(表现在强类型语言,就是传参类型确定了),根据传入参数的不同,可以做出不同的处理方式,
#java c++ c# —— 强类型语言
# shell语言 —— 弱类型语言,可以混合使用类型,
# 介于 强类型 与 弱类型之间 —— python 动态强类型语言




class Payment:
    def pay(self):pass

class QQpay(Payment):
    def pay(self,money):
        print('使用qq支付了%s元'%money)

class Wechatpay(Payment):
    def pay(self,money):
        print('使用微信支付了%s元'%money)
    def recharge(self):pass

# def pay(Payment pay_obj,int money):
#     pay_obj.pay(money)
#这两行代码,会报错,因为python中是没有"类型 变量"的形式的,
#这里主要是想通过强类型语言函数传参的规律:即在java和c++中,有共同父类的子类对象,可以当作父类对象类型的变量,在函数参数中进行传递,
#进而说明,python2.*和3.*中,是自带多态效果的,即不要有那个共同的父类来进行约束,只要两个类中有相同的方法,
#也可能是因为在python3中,所有的类都默认继承自object类,而python2中虽然不是默认继承自object类,但是内部可能有某种机制,





# 鸭子类型
class QQpay():
    def pay(self,money):
        print('使用qq支付了%s元'%money)

class Wechatpay():
    def pay(self,money):
        print('使用微信支付了%s元'%money)

def pay(pay_obj,money):
    pay_obj.pay(money)

def func_test(s):
    s.pay(100)
    
func_test(Wechatpay())
func_test(QQpay())


# 鸭子类型
#不是通过继承关系来约束某些类中必须有哪些方法名
#是通过一种约定俗成的方式来保证在多个类中相似的功能叫相同的名字
#是一种默契,程序员级别的规范,而不是编译器层级的规范,坏处就是容易违规,


下面两张图,第一张是说抽象类的语法,第二张也挺重要,为什么呢?


大数据第一季--java基础(day21)

大数据第一季--java基础(day21)
  • 2017年01月21日 10:13

Day21第二十一天 java基础 -------IO流

------- android培训、java培训、期待与您交流! ---------- 1、ObjectinputStream ObjectOutputStream 为直接操对象的流,将堆内存中...
  • xingyan_wei
  • xingyan_wei
  • 2012-11-26 19:59:23
  • 396

传智播客-Java学习笔记day21

1.编码表概述和常见编码表   计算机只能识别二进制数据,早期由来是电信号。 为了方便应用计算机,让它可以识别各个国家的文字。 就将各个国家的文字用数字来表示,并一一对应,形成一张表。 ASCII...
  • x380481791
  • x380481791
  • 2017-07-31 16:59:01
  • 147

30天自制操作系统day21

用C语言编写应用程序要调用API,需要将参数放到寄存器中然后中断,C语言中没有这样的指令,所以写一个汇编函数:_api_putchar: ; void api_putchar(int c); ...
  • u012399761
  • u012399761
  • 2015-07-26 12:07:29
  • 661

毕向东Java视频学习笔记【day21-IO流<2>】

23-IO流(演示键盘录入)一旦 System.in流 被关闭了,再创建一个对象in2没有用,会抛出异常。 InputStream in = System.in; int ...
  • qq_24653023
  • qq_24653023
  • 2016-09-05 17:25:22
  • 741

Java基础笔记Day21

21.01_IO流(字符流FileReader) 1.字符流是什么 字符流是可以直接读写字符的IO流 字符流读取字符, 就要先读取到字节数据, 然后转为字符. 如果要写出字符, 需要把字符转为字节再...
  • Itheima_YinZhong
  • Itheima_YinZhong
  • 2017-01-04 23:06:43
  • 122

黑马程序员_java基础day21

------- android培训、java培训、期待与您交流! ---------- 主要内容:一、对象的序列化;二、管道流;三、RandomAccessFile;四、操作基本数据类型;五、操...
  • u010348414
  • u010348414
  • 2013-06-03 08:46:44
  • 281

day21

Android环境配置首先要有java环境 eclipseIDE AndroidSDK ADT(Google宣布不再更新ADT,ADT是eclips插件) eclipse安装ADT插件 关联And...
  • l357774631
  • l357774631
  • 2015-08-17 21:19:00
  • 132

Day21

排序 Wikipedia 排序算法 冒泡 void BubbleSort(int[] a) { if(a == null || a.Length == 0) { ...
  • SillyLazyBird
  • SillyLazyBird
  • 2018-02-14 23:14:43
  • 31

python学习—Day21—json

json json的四种方法: json.loads json.dumps 多个s的就是来处理字符串的,没有多s的就是用来处理文件的 json.load json.dump ...
  • shiyan1sheng
  • shiyan1sheng
  • 2017-11-13 12:32:18
  • 62
收藏助手
不良信息举报
您举报文章:python基础-day21
举报原因:
原因补充:

(最多只允许输入30个字)