组合 什么有什么的关系
一个类的对象作为另一个类的对象
继承
子类可以使用父类中的名字(静态属性 方法)
抽象类和接口类
只能不继承,不能被实例化
子类必须实现父类中的同名方法———规范代码
metaclass=ABCMeta @abstractmethod
python 支持多继承,对于python 来说,抽象类和接口类没有区别
接口类是python 特有的,因为Pythonz直接用类就可以实现接口的效果
python没有'接口'这种数据类型,java中有
继承
多态
封装
property
classmethod
staticmethod 钻石继承
class A:
def func(self):print('in A')
class B(A):
def func(self):print('in B')
class C(A):
def func(self):print('in C')
class D(B,C):
def func(self): print('in D')
d=D()
d.func()#in D class A:
def func(self):print('in A')
class B(A):pass
# def func(self):print('in B')
class C(A):pass
# def func(self):print('in C')
class D(B,C):pass
# def func(self): print('in D')
d=D()
d.func()#in A
钻石继承--4个类图形
D->B->C->A
class E:
def func(self):print('in E')
class D:
def func(self):print('in D')
class C(E):
def func(self):print('in C')
class B(D):pass
# def func(self):print('in B')
class A(B,C):pass
# def func(self):print('in A ')
d=D()
d.func()#in D 走最合理的路 class F:
def func(self):print('in F')
class E(F):
def func(self):print('in E')
class D(F):
def func(self):print('in F')
class C(E):
def func(self):print('in C')
class B(D):
def func(self):print('in B')
class A(B,C):
def func(self):print('in A')#遵循广度优先的原则
print(A.mro())#打印的是A 的找值顺序[<class '__main__.A'>, <class '__main__.B'>, ...]A,B,D,C,E,F
super
class List(list):
def append(self, obj):
if type(obj) is str:
super().append(obj)#调用父类的方法,list.append(obj)
else:
# print(f'{obj}不是字符串类型')
print('%s不是字符串类型' % obj) def show_middle(self):
return self[int(len(self) / 2)]#返回以长度的一半为索引的self的值 li = List('hello word22222')#['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'd', '2', '2', '2', '2', '2', '18', 'abc']
li.append('')
li.append('abc')
print(li)
print(li.show_middle())#r

class A:
def func(self):
print('A')
class B(A):
def func(self):
print('B')
super().func()
class C(A):
def func(self):
print('C')
super().func()
class D(B,C):
def func(self):
print('D')
super().func()
D().func()#D,B,C,A
print(D.mro())#打印的是A 的找值顺序D->B->C->A
B().func()#B,A
print(B.mro())#打印的是A 的找值顺序B->A
super并不是单纯的找父类,和mro的顺序是玩完全对应的
新式类:python 3里全部是新式类
新式类默认继承object
py2里面
新式类 主动继承object
经典类 不主动继承object--遵循深度优先算法,没有mro 方法,没有super
python  动态强类型语言
弱类型 1+'' 参数的数据类型也不需要指定
强类型 同类型之
间可以做运算 参数的数据类型也需要指定
在python的经典类中,方法解析顺序是深度优先算法
事实上,对于你定义的每一个类,Python 会计算出一个方法解析顺序(Method Resolution Order, MRO)列表它代表了类继承的顺序
在Python的新式类中,方法解析顺序并非是广度优先的算法,而是采用C3算法,只是在某些情况下,C3算法的结果恰巧符合广度优先算法的结果。

C3算法的本质就是Merge,不断地把mro()函数返回的序列进行Merge,规则如下:

1. 如果第一个序列的第一个元素,是后续序列的第一个元素,或者不再后续序列中再次出现,则将这个元素合并到最终的方法解析顺序序列中,并从当前操作的全部序列中删除。

2. 如果不符合,则跳过此元素,查找下一个列表的第一个元素,重复1的判断规则

举例:

# 归并算法 C3算法
class A:pass
class B(A):pass
class C(A):pass
class D(B):pass
class E(C):pass
class F(D,E):pass # 第一步 先找出F类的父类的MRO
D [D,B,A,O]
E [E,C,A,O]
# 变形为:merge([D,B,A,O], [E,C,A,O], [D,E])
# 第一个表的表头 后面所有的表去掉表头部分不能含有这个D
FD merge([B,A,O], [E,C,A,O], [E]) # 先将D取出来
FDB merge([A,O], [E,C,A,O], [E]) # 再将B取出来
# 不满足条件时 取二个
FDBE merge([A,O], [C,A,O]) # 将第二个列表E取出来
FDBEC merge([A,O], [A,O]) # 将第二个列表里的C取出来,此时取值完成
FDBECAO # F的继承顺序为FDBECAO
# 注意:这是模仿内部的查找机制做的示例,并非真实原理
多态
python天生自带多态
什么是多态
java多态
class Foo:pass
class list(Foo):pass
class dict(Foo):pass
class str(Foo):pass
def len(a):
print(a)
len(1)

封装

封装成一个函数
封装成一个类 封装 面向对象的特性
class A:
__静态属性='aaa' #私有的静态属性
print(__静态属性)#aaa __静态属性,在内部的储存方式为_类名__名字,例如_A__静态属性
在一个变量前加上两个下划线是有特殊意义的,将变量变成私有的 print(A.__静态属性)#报错,私有的名字不能在类的外部使用
print(A.__dict__)#将类的内容打印出来
print(A._A__静态属性)#从语法的角度上不允许直接调用 aaa
A.__wahahaha='hahaha'#在一个类的外部是不可能定义一个私有名字的 ,此处的hahaha是普通变量
print(A.__dict__)
私有的对象属性
class Room:
def __init__(self,owner,id,length,width,height):
self.owner=owner
self.id=id
self.__length=length
self.__width=width
self.__height=height
def area(self):
return self.__length*self.__width #这里 self.__length在内存里是self._Room__length
r=Room('小灰灰',301,1,1,0.5)
print(r.area())#
私有的方法
不希望从外部去调用这个方法,不独立完成一个功能,而是类整体完成某个功能的一部分
class Student:#理解
def __init__(self,name,pwd):
self.name=name
self.__pwd=pwd
def __getpwd(self):
return self.__pwd[::-1]
def login(self):
return self.__getpwd()
s=Student('xiaohua','abc')
print(s.login())#cba

class A:
def __init__(self):
self.func()
def func(self):
print('A') class B(A):
def func(self):
print('B') B()#B 用的是父类class A 的__init__方法,调用的是自己的func函数 class A:
def __init__(self):
self.__func() #_A__func
def __func(self):
print('A')
class B:
def __func(self):
print('B')
def __init__(self):
self.__func() #_B__func
B()#B class A:
def __init__(self):
self.__func() #_A__func
def __func(self):
print('A')
class B:
def __init__(self):
self.__func() #_B__func
B()#报错,找不到_B__func的对象
名字
共有的 在类的外部用 内部用 子类用
私有的 在类的内部用 私有的概念和面试题 ***
私有的属性和静态属性***
私有方法** 几个装饰器函数
property
classmothod
staticmethod
装饰器
圆形
半径r
面积area
周长 perimeter
from math import pi
class Circle:
def __init__(self,r):
self.r=r
@property#将一个方法伪装成一个属性
def area(self):
return pi*self.r**2
@property
def perimeter(self):
return 2*pi*self.r
r1=Circle(3)
print(r1.area)#相当于不加装饰前的r1.area()
print(r1.perimeter)#相当于不加装饰前的r1.perimeter()
class Person:
def __init__(self,name):
self.__name=name
@property#将一个方法伪装成一个属性
def name(self):
return self.__name
@name.setter#将这个属性进行修改
def name(self,new):
if type(new) is str:
self.__name=new
a=Person('egon')
print(a.name)#egon
a.name='alex'#不能直接改
print(a.name)#alex

class Demo:
def __init__(self,wahaha):
self.__wahaha=wahaha
@property#将一个方法伪装成属性
def wahaha(self):
print('in wahaha')
return self.__wahaha
@wahaha.setter
def wahaha(self,new):
self.__wahaha=new
d=Demo('abc')
print(d.wahaha)#123 可以被查看
d.wahaha=123#可以被修改
print(d.wahaha)#

class Goods:
def __init__(self,discount,origin_price):
self.__discount=discount
self.__price=origin_price
@property
def price(self):
return round(self.__discount*self.__price,2)#保留两位小数
@price.setter
def price(self,new):
self.__price=new
d=Goods(0.8,10)
print(d.price)#8.0
d.price=12
print(d.price)#9.6
一个属性
可以被查看
可以被修改
可以被删除
class A:pass
a=A()
a.name='egon'
print(a.__dict__)#{'name': 'egon'}
del a.name
print(a.__dict__)#{}

class A:
def __init__(self, path):
self.__f = open(path, 'w') # 创建属性的方式可以改变
@property
def f(self):
return self.__f
@f.deleter
def f(self):
self.close()#所有的借用操作系统的资源,在删除一个变量之前必须先归还资源
del self.__f
def write(self,content):
self.__f.write(content)
def close(self):
self.__f.close()#上面的self.close()=self.__f.close()
obj=A('heheda')
obj.write('窗前明月光,地上鞋两双')
obj.close()#所有的借用操作系统的资源,在删除一个变量之前必须先归还资源 del obj.f#f 文件删除,文件没有关
print(obj.f)
property***
setter**
deleter*
class Goods:
__discount=0.8
def __init__(self,origin_price):
self.__price=origin_price
@property
def price(self):
return round(self.__price*Goods.__discount,2)#Goods.__discount.调用静态变量
@price.setter
def price(self,new_price):
self.__price=new_price
@classmethod
def change_discount(cls,new_discount):
print(cls,Goods)#此时的cls和Goods是一样的
Goods.__discount=new_discount
# cls.__discount=new_discount
banana=Goods(10)
print(banana.price)#
banana.change_discount(1)#10 恢复原价
print(banana.price)

class Student:
def __init__(self,name,sex):
self.name=name
self.sex=sex
@staticmethod #相当于函数
def login():
name=input('>>')
if name=='alex':
print('登录成功')
# 学生的登录行为
Student.login()
method            方法--函数                          由实例化对象去调用
property 伪装成属性的一种方法 --特性 由实例化对象去调用
classmethod 类方法 由类调用,只用用类中的静态变量
staticmethod 静态方法 由类调用,一个方法既不会用到对象的属性,也不会用到类的属性

初识面向对象(钻石继承,super,多态,封装,method,property,classmethod,staticmethod)的更多相关文章

  1. Python 面向对象编程 继承 和多态

    Python 面向对象编程 继承 和多态 一:多继承性 对于java我们熟悉的是一个类只能继承一个父类:但是对于C++ 一个子类可以有多个父亲,同样对于 Python一个类也可以有多个父亲 格式: c ...

  2. Day7 初识面向对象,面向对象之继承、多态和封装

    一.面向对象引言 一.面向对象的程序设计的由来 详述见:http://www.cnblogs.com/linhaifeng/articles/6428835.html 二.面向对象引子 写一个简单程序 ...

  3. python学习第十五天 -面向对象之继承和多态

    大家都知道面向对象的三大特性:封装,继承,多态.封装特性在上一章节已经讲解过.这一章节主要讲解继承和多态. 继承: 当定义一个类的时候,可以从现有的类进行继承.那么新定义的类可以称为子类,被继承的现有 ...

  4. javascript面向对象:继承、多态

    继承 js中同样可以实现类的继承这一面向对象特性,继承父类中的所有成员(变量和属性),同时可扩展自己的成员,下面介绍几种js中实现继承的方式: 1,对象模仿:通过动态的改变 this 指针的指向,实现 ...

  5. Python面向对象:继承和多态

    继承与多态简介: 继承可以把父类的所有功能都直接拿过来,这样就不必重零做起,子类只需要新增自己特有的方法,也可以把父类不适合的方法覆盖重写. 动态语言的鸭子类型特点决定了继承不像静态语言那样是必须的. ...

  6. php 面向对象之继承、多态和静态方法

    <?php //继承:子类可以继承父类的一切 //特点:单继承 //父类 class Ren { public $name; public $sex; public $yuyan; functi ...

  7. Java:[面向对象:继承,多态]

    本文内容: 继承 多态 首发时期:2018-03-23 继承: 介绍: 如果多个类中存在相同的属性和行为,可以将这些内容抽取到单独一个类中,那么多个类(子类)无需再定义这些属性和行为,只要继承那个类( ...

  8. python面向对象 : 抽象类(接口类),多态,封装(私有制封装)

    一. 抽象类(接口类) 与java一样, python也有抽象类的概念但是同样需要借助模块实现,抽象类是一个特殊的类, 它的特殊之处在于只能被继承, 不能被实例化. 从设计角度去看, 如果类是从现实对 ...

  9. 【学习笔记】--- 老男孩学Python,day18 面向对象------抽象类(接口类), 多态, 封装

    抽象类,接口类 Python没有接口这个概念 抽象类(接口类): 目的是制定一个规范 要学会归一化设计,有重复的东西就要想把它们合并起来 from abc import ABCMeta, abstra ...

随机推荐

  1. 学习使用junit4

    目录 一.junit介绍 二.junit4的简单使用

  2. Python十大装B语法

    https://blog.csdn.net/xufive/article/details/102856921

  3. xshell的ssh连接频繁提示Socket error Event: 32 Error: 10053(待验证)

    修改/etc/ssh/sshd_config下的配置文件 将ClientAliveInterval的值修改为60 然后重启ssh服务器 目前没有在频繁出现ssh断开问题了,应该是有效的

  4. [LeetCode] 107. Binary Tree Level Order Traversal II 二叉树层序遍历 II

    Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left ...

  5. 【Sqoop学习之一】Sqoop简介

    环境 sqoop-1.4.6 Sqoop:将关系数据库(oracle.mysql.postgresql等)数据与hadoop数据进行转换的工具. 两个版本:两个版本完全不兼容,sqoop1使用最多:s ...

  6. 使用无图形界面启动Centos

    Centos有些时候我们是不需要图形界面的 centos默认安装成功后是有图形界面的,为了减少系统开销,有时候我们需要无图形界面启动linux(centos7) systemctl set-defau ...

  7. Connection to api@localhost failed. [08001] Could not create connection to d

    pycharm 换成2019之后连接数据库用户名密码数据库名字都没错,就是连接不上去,网上百度一下,试试将URL后面拼接 ?useSSL=false&serverTimezone=UTC 发现 ...

  8. Python开发之virtualenv和virtualenvwrapper详解

    在使用 Python 开发的过程中,工程一多,难免会碰到不同的工程依赖不同版本的库的问题: 亦或者是在开发过程中不想让物理环境里充斥各种各样的库,引发未来的依赖灾难. 此时,我们需要对于不同的工程使用 ...

  9. Python中的条件判断、循环以及循环的终止

    条件判断 条件语句是用来判断给定条件是否满足,并根据判断所得结果从而决定所要执行的操作,通常的逻辑思路如下图: 单次判断 形式 if <判断条件>: <执行> else: &l ...

  10. [LOJ#3120][Luogu5401][CTS2019]珍珠(容斥+生成函数)

    https://www.luogu.org/blog/user50971/solution-p5401 #include<cstdio> #include<algorithm> ...