抽象类,接口类,封装,property,classmetod,statimethod(类方法,静态方法)

一丶抽象类和接口类

 接口类(不崇尚用)

    接口类:是规范子类的一个模板,只要接口类中定义的,就应该在子类中实现
    接口类不能被实例化,只能被继承
    支持多继承,父类不实现

    python 本身支持多继承,没有接口专用的语法。但是得知道接口的概念

例子:

class Alipay:
'''
支付宝支付
'''
def pay(self,money):
print('支付宝支付了%s元'%money) class Applepay:
'''
apple pay支付
'''
def pay(self,money):
print('apple pay支付了%s元'%money) class Wechatpay:
def fuqian(self,money):
'''
实现了pay的功能,但是名字不一样
'''
print('微信支付了%s元'%money) def pay(payment,money):
'''
支付函数,总体负责支付
对应支付的对象和要支付的金额
'''
payment.pay(money) p = Wechatpay()
pay(p,200) #执行会报错

第一种解决方式(比较low)

class Payment:
def pay(self):
raise NotImplementedError class Wechatpay(Payment):
def fuqian(self,money):
print('微信支付了%s元'%money) p = Wechatpay() #这里不报错
pay(p,200) #这里报错了

第二种(高级方式)

from abc import ABCMeta,abstractmethod
# 接口类:
# 是规范子类的一个模板,
# 只要接口类中定义的,就应该在子类中实现(规范所有支付功能必须实现pay方法)
# 接口类不能被实例化,它只能被继承
# 支持多继承
class Payment(metaclass=ABCMeta): #模板,接口类
@abstractmethod #装饰接口类中方法的,加上这个装饰器,自动检测子类中的方法名
def pay(self,money):pass @abstractmethod
def get(self):pass # 收钱功能 class Apple_Pay(Payment):
def pay(self,money):
print('您使用苹果支付支付了%s元'%money) class Ali_Pay(Payment):
def pay(self, money):
print('您使用支付宝支付了%s元' % money) class WeChat_Pay(Payment):
def pay(self,money):
print('您使用微信支付了%s元' % money) def pay(obj,money):
return obj.pay(money)

  

#接口类 : 多继承,父类不实现
from abc import ABCMeta,abstractmethod
class Fly_Animal(metaclass=ABCMeta): #规范
@abstractmethod
def fly(self):pass class Swim_Animal(metaclass=ABCMeta):
@abstractmethod
def swim(self): pass class Walk_Animal(metaclass=ABCMeta):
@abstractmethod
def walk(self): pass class Frog(Walk_Animal,Swim_Animal):
def walk(self):
print('自己实现walk功能') def swim(self): pass class Swan(Walk_Animal,Swim_Animal,Fly_Animal):
pass class Bird(Walk_Animal,Fly_Animal):
pass
接口隔离原则: 使用多个专门的接口,而不使用单一的总接口。即客户端不应该依赖那些不需要的接口。

  抽象类

  抽象类可以实现一些子类共有的功能和属性\抽象类不鼓励多继承

  python 没有接口的概念  

  只能借助抽象类的模块 来实现接口类  

  接口 —— java : 没有多继承 —— Interface

from abc import ABCMeta,abstractmethod
class Base(metaclass=ABCMeta):
def __init__(self,filename):
self.filename = filename
@abstractmethod #抽象方法
def open(self):
return 'file_handler' @abstractmethod
def close(self):pass @abstractmethod
def read(self):pass @abstractmethod
def write(self):pass class File(Base):
def open(self):pass
def close(self):pass
def read(self):pass
def write(self):pass # 抽象类不能被实例化
# 这个抽象类可以规范子类必须实现抽象类中的抽象方法

二、封装(重要)

    封装: 隐藏对象的属性和实现细节,仅对外提供公共访问方式

    把一些属性和方法放到类里 这本身就是一种封装(广义上的封装)
    面对对象里的封装 : 把属性和方法藏在类里 我只能在类内部调用,不能再外部使用(实际意义)

   好处: 

    1. 将变化隔离; 2. 便于使用;3. 提高复用性; 4. 提高安全性;

   原则:

    1. 将不需要对外提供的内容都隐藏起来;

    2. 把属性都隐藏,提供公共方法对其访问。

加__藏起来
class Dog:
__role = 'dog' # 私有的静态属性,在语法上是可以把类的数据属性设置成私有的如__N,会变形为_Dog__N
def func(self): # 内部使用
print(Dog.__role) # _Dog__role 私有方法
# print(Dog.role)
print(Dog.__dict__) # 查看名字空间
print(Dog._Dog__role)# 不鼓励这样调用私有变量 dog 查私有静态属性
从类的外面不能直接调用,在类内的使用加上了一层密码:_类名 d = Dog() #能实例化
d.func()
私有动态方法
class Dog:
__role = 'dog' # 私有的静态属性
def __discount(self):
print('in __func') # 私有方法 (动态) def price(self):
self.__discount() print(Dog.__dict__)
print(Dog._Dog__discount)
定义一个私有变量\属性\方法:__名字
在类的内部可以直接使用: __名字
在类的外部不能直接使用,如果一定要用,在私有方法之前加上:_类名,变成_类名__名字 # 不推荐使用
在类外的名字 通过__dict__就可以查看

私有的
私有的静态属性、方法、对象属性
使用__名字的方式调用,保证在类内部可以调用,外部不行 class Room:
def __init__(self,name,price,length,width):
self.name = name
self.price = print
self.__length = length # 私有的对象属性
self.__width = width def area(self):
return self.__length*self.__width house = Room('天空之镜',100000,200,1)
print(house.area())
私有属性能否被继承: 不能
私有的 不能被继承
当有一个名字,不想被外部使用也不想被子类继承,只想内部使用的时候就定义私有的
class A:
def __func(self):
print('__a_func') _A__func class B(A):
def __init__(self):
self.__func()    _B__func b= B() # 报错

三、property内置(会使代码变整洁)

        property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值 

例子:1、

@property 把一个方法 伪装成一个属性
1 属性的值 是这个方法的返回值
2 这个方法不能有参数
class Person:
def __init__(self,name,height,weight):
self.name = name
self.height = height
self.weight = weight # @property 加了方法变属性
def bmi(self): #bmi人的一个属性
self.weight/(self.height ** 2) li = Person('lishi',1.65,50)
print(li.bmi) # 属性
print(li.bmi()) # 方法
2、
圆形类
from math import pi
class Circle:
def __init__(self, r):
self.radius = r @property
def perimeter(self):
return 2 * pi * self.radius @property
def area(self):
return pi * (self.radius ** 2) c1 = Circle(5)
print(c1.area)

class Goods:
discount = 0.8 # 静态属性
def __init__(self,name,price):
self.name = name
self.__price = price # 原价 @property
def price(self): # 折后价
return self.__price * Goods.discount apple = Goods('榴莲',10)
print(apple.price) # 8.0
banana = Goods('香蕉',2.5)
print(banana.price) 2.0 apple.price = 6 # 修改不了原价
print(apple.price) # 报错

解决:setter

class Goods:
discount = 0.8 # 静态属性 全部打8折
def __init__(self,name,price):
self.name = name
self.__price = price # 原价 @property
def price(self): # 折后价
return self.__price * Goods.discount @price.setter # 加红的名字必须一样的才会有效果
def price(self,new_price): # 修改原价
     # if type(new_price) is int: # 加了,可以增加安全性,使用setter的优势
self.__price = new_price
        # self.__price = new_price
apple = Goods('苹果',20) # 原价
apple.price = 10 # 修改原价(只能传一个参数) setter
print(apple.price) # property
封装
__私有+property
让对象的属性变得更安全了
获取到的对象的值可以进行一些加工
修改对象的值的同时可以进行一些验证 setter

一个静态属性property本质就是实现了get,set,delete三种方法


class Foo:
@property # 把AAA伪装成一个属性
def AAA(self):
print('get的时候运行我啊') @AAA.setter # 修改值
def AAA(self,value):
print('set的时候运行我啊') @AAA.deleter # 删除
def AAA(self):
print('delete的时候运行我啊') #只有在属性AAA定义property后才能定义AAA.setter,AAA.deleter
f1=Foo()
f1.AAA
f1.AAA='aaa'
del f1.AAA

class Foo:
def get_AAA(self):
print('get的时候运行我啊') def set_AAA(self,value):
print('set的时候运行我啊') def delete_AAA(self):
print('delete的时候运行我啊')
AAA=property(get_AAA,set_AAA,delete_AAA) #内置property三个参数与get,set,delete一一对应 f1=Foo()
f1.AAA
f1.AAA='aaa'
del f1.AAA

使用:


class Goods:
__discount = 0.8 #静态属性
def __init__(self,name,price):
self.__name = name
self.__price = price #原价
@property
def name(self):
return self.__name @name.setter
def name(self,new_name):
self.__name = new_name @name.deleter
def name(self):
del self.__name @property
def price(self): #折后价
return self.__price * Goods.__discount @price.setter
def price(self,new_price): #修改原价
if type(new_price) is int:
self.__price = new_price apple = Goods('苹果',10)
del apple.name
print(apple.name) # 报错,已删除

四、classmethod和staticmthod(类方法、静态方法)

问题:定义一个类类里面的方法并没有用到self
例如:
# 与apple无关,所以def change_discount(self,new_discount)在这里不适合
# 需实例化
class Goods:
__discount = 0.8
def change_discount(self,new_discount):
Goods.__discount = new_discount
apple = Goods() # 实例化
apple.change_discount(0.75)

修改版

类方法:

class Goods:
__discount = 0.8
@classmethod #类方法
def change_discount(cls,new_discount):
cls.__discount = new_discount
@classmethod
def get_discount(cls):
return cls.__discount
# apple = Goods()
Goods.change_discount(0.75)
print(Goods.get_discount())

类方法好处:
  调用:不需要实例化 直接用类名调用就好
  定义:不用接受self参数,默认传cls,cls就代表当前方法所在的类

什么时候用类方法?
需要使用静态变量 且 不需要和对象相关的任何操作的时候

静态方法:
  如果这个方法 既不需要操作静态变量也不需要使用对象相关的操作,就使用静态方法

class A:
@staticmethod
def func(name): #静态方法
print(123)
A.func('alex')
class A:
@staticmethod
def func(): #静态方法
print(123)
A.func()
面向对象编程:专门为面向对象编程提供的一个方法——staticmethod
它完全可以当做普通函数去用,只不过这个函数要通过类名.函数名调用
其他 传参 返回值 完全没有区别 类里面,一共可以定义这三种方法:
普通方法 self
类方法 cls @classmrthod
静态方法 @staticmethod
绑定方法 和 非绑定方法

class A:
@staticmethod
def func1(name): #静态方法
print(123) @classmethod
def func2(cls): # 静态方法
print(123) def func3(self):pass
a = A()
print(a.func1) #静态方法
print(a.func2) #类方法 : 绑定到A类的func
print(a.func3) #普通方法:绑定到A类对象的func

静态方法和类方法 都是直接可以使用类名调用
普通方法:对象调用
类能解决的事,没必要搞个实例化对象能弄
 

抽象类,接口类,封装,property,classmetod,statimethod的更多相关文章

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

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

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

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

  3. python day - 19 抽象类 接口类 多态 封装

    一. 抽象类接口类即制定一个规范 特点: 1.不可被实例化. 2.规范子类当中必须事先某个方法. 3.在python中有原生实现抽象类的方法,但没有原生实现接口类的方法. 例题:制定一个规范就是,子类 ...

  4. python 全栈开发,Day21(抽象类,接口类,多态,鸭子类型)

    一.昨日复习 派生方法和派生属性 super 只有在子父类拥有同名方法的时候, 想使用子类的对象调用父类的方法时,才使用super super在类内 : super().方法名(arg1,..) 指名 ...

  5. python笔记5 接口类抽象类 封装 反射 设计模式 模块 :random随机数 josn shelve持久化存储

    接口类抽象类 接口类:接口类就是制定一个规则,让其他人按照我的规则去写程序. #!/usr/bin/env python from abc import ABCMeta,abstractmethod ...

  6. python's twenty-first day for me 抽象类和接口类以及多态

    归一化设计: 不管是哪一个类的对象,都调用同一个函数去完成相似的功能. class Alipay: def pay(self,money): print('使用支付宝支付了%s' % money) c ...

  7. Python面向对象 | 抽象类和接口类

    一.抽象类(规范的编程模式) 什么是抽象类 抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化.抽象类的本质还是类,指的是一组类的相似性,而接口只强调函数属性的相似性. 为什么要有抽象类 ...

  8. 2019-03-28-day021-抽象类与接口类

    今日内容 type和class 继承 抽象类 接口类 多态 java 鸭子类型 pickle模块 collections.namedtuple type和class ##type ##class pr ...

  9. python学习之老男孩python全栈第九期_day025知识点总结——接口类、抽象类、多态、封装

    一. 接口类 java:面向对象编程 设计模式 -- 接口类 接口类:python原生不支持 抽象类:python 原生支持的 from abc import abstractclassmethod, ...

随机推荐

  1. ReportView显示本地报表

    from:http://www.cnblogs.com/duanshuiliu/archive/2012/07/13/2589862.html 使用ReportView控件可以显示远端Report s ...

  2. LeetCode:棒球比赛【682】

    LeetCode:棒球比赛[682] 题目描述 你现在是棒球比赛记录员.给定一个字符串列表,每个字符串可以是以下四种类型之一:1.整数(一轮的得分):直接表示您在本轮中获得的积分数.2. " ...

  3. vue项目配置less预编译语言

    当所有东西都 准备好之后 : 第一步: 安装less依赖,npm install less less-loader --save 第二步:找到webpack配置文件webpack.base.conf. ...

  4. shell-一些有趣的使用

    1. 对字符串进行MD5加密  echo test |md5sum|awk '{print $1}' 字符串数量很多时可以这样做: echo test |md5sum|awk '{print $1}' ...

  5. 详细解读ARM寄存器之CPSR【转】

    本文转载自:https://blog.csdn.net/david_luyang/article/details/6276533 详细解读ARM寄存器之CPSR 整理人:卢阳 QQ:820927872 ...

  6. SpringBoot 事务隔离性和传播性

    propergation 传播性 Spring中七种Propagation类的事务属性详解:  REQUIRED:支持当前事务,如果当前没有事务,就新建一个事务.这是最常见的选择.  SUPPORTS ...

  7. HDU 1176 免费馅饼 简单动态规划

    世道很简单的动态规划,但是却错了,让我很无语,改来改去还是不对,第二天有写就对了,之后我就耐着性子慢慢比较之前的错误代码,发现 第一次错:纯粹用了a[i][j]+=max3(a[i+1][j-1], ...

  8. LeetCode——Maximum Depth of Binary Tree

    LeetCode--Maximum Depth of Binary Tree Question Given a binary tree, find its maximum depth. The max ...

  9. 【Node.js】'readline' 逐行读取、写入文件内容

    [转]运用readline逐行读取的两种实现 效果图如下: 左边1.log 为源文件 右边1.readline.log为复制后的文件 下边为命令行输出 实现方式一: [javascript] view ...

  10. JNIjw04

    1.VC6(CPP)的DLL代码: #include<stdio.h> #include "jniZ_JNIjw04.h" #include <string> ...