python中的面向对象

1.什么是类?什么是对象?
类是具有相同属性和技能一组对象的抽象
对象是类实例化的结果,用来描述一个具体的事物
比如猫是一个类,而我养的猫是一个对象

2.创建一个猫类并实例化的代码

class Cat():
    def __init__(self,name,age,color):
        self.name = name
        self.age = age
        self.color = color

    def talk(self):
        print('%s叫了一声miao'%(self.name))

xmt = cat('小馒头','5','white')

3.以上代码的执行顺序
以上面的猫类为例:
1.首先创建一个内存空间,Cat指向这块内存空间
2.在内存空间中存入__init__、talk的内存地址
3.再创建一块内存空间,self指向这块内存空间,同时创建一个类指针,指向类
4.在这块空间中存入name、age、color的值
5.执行结果返回给对象xmt
在这里插入图片描述
4.类中有哪些东西
静态变量、实例变量、绑定方法、类方法、静态方法

5.什么是组合
一个类是另一个类的属性,如下,先定义了一个圆类,然后定义了一个圆环类,圆类是圆环类的一个属性

from math import pi

class Circle():
    def __init__(self,r):
        self.r = r

    def area(self):
        return pi * self.r * self.r

    def circf(self):
        return pi * self.r * 2

class Ring():
    def __init__(self,outr,inr):
        self.outr = Circle(outr)
        self.inr = Circle(inr)

    def area(self):
        return self.outr.area() - self.inr.area()

    def circf(self):
        return self.outr.circf() + self.inr.circf()

ring1 = Ring(10,5)
print(ring1.area(),ring1.circf())

6.类的继承
6.1什么是新式类?什么是经典类?
继承了object的类都是新式类,不继承object类的类是经典类
在py3中,所有类都是新式类,在py2中,主动继承了object类的类是新式类,其他类是经典类
6.2 类继承的顺序
在单继承中,经典类与新式类没有区别
在多继承中,经典类遵循深度优先,新式类遵循C3算法,可通过类名.mro()来查看继承顺序
6.3抽象类
抽象类是一种规范,用于约束子类实现抽象类同名的方法,有两种实现方式
比如支付类有两个子类支付宝支付类和微信支付类,都要实现支付功能
方式1:在调用Alipay或Wechatpay的pay方法时,如果没有重写pay方法,就会报错

class Payment():
    def pay(self,money):
        raise NotImplementedError('没有实现pay方法')

class Alipay(Payment):
    def __init__(self,name):
        self.name = name

    def pay(self,money):
        print('%s使用Alipay支付%s'%(self.name,money))

class Wechatpay(Payment):
    def __init__(self, name):
        self.name = name

    def pay(self,money):
        print('%s使用wechatoay支付%s' % (self.name, money))

方式2:引用模块,这种方式约束力强

from abc import ABCMeta,abstractmethod

class Payment(metaclass=ABCMeta):
    @abstractmethod
    def pay(self,money):
        raise NotImplementedError('没有实现pay方法')

class Alipay(Payment):
    def __init__(self,name):
        self.name = name

    def pay(self,money):
        print('%s使用Alipay支付%s'%(self.name,money))

class Wechatpay(Payment):
    def __init__(self, name):
        self.name = name

    def pay(self,money):
        print('%s使用wechatoay支付%s' % (self.name, money))

def pay(name,money,kind):
    if kind == 'Alipay':
        obj = Alipay(name)
    elif kind == 'Wechatpay':
        obj = Wechatpay(name)
    obj.pay(money)

pay('傅马甲',100,'Alipay')

6.4 super方法
1.super方法如何执行?
把所有的父类方法执行一遍,不重复执行,顺序遵循C3算法,通过类名.mro()查看
2.super的执行顺序

class A(object):
    def func(self):
        print('A')
class B(A):
    def func(self):
        super().func()
        print('B')
class C(A):
    def func(self):
        super().func()
        print('C')
class D(B,C):
    def func(self):
        super().func()
        # super(D,self).func()
        print('D')
D().func()
print(D.mro())

执行的结果为A C B D
mro显示的顺序为[<class ‘main.D’>, <class ‘main.B’>, <class ‘main.C’>, <class ‘main.A’>, <class ‘object’>]
3.super的例子
比如一个视频收费网站有普通用户User类,有一个VIP用户Vipuser类,可以通过super调用父类的__init__方法

class User:
    def __init__(self,name):
        self.name = name
class VIPUser(User):
    def __init__(self,name,level,strat_date,end_date):
        # User.__init__(self,name)
        super().__init__(name)              # 推荐的
        # super(VIPUser,self).__init__(name)
        self.level = level
        self.strat_date = strat_date
        self.end_date = end_date

**7.多态
7.1什么是多态?
一个类表现出的多种状态,如6.3中的Payment类表现出Alipay、Wechatpay两种状态
7.2其他语言中的多态
JAVA中参数必须指定类型,如6.3中的pay函数,kind必须制定一个类型,为了让kind可以传Alipay和Wechatpay两个类,必须让他们继承同一个父类Payment。
而在python中,处处是多态。

8.封装
8.1什么是封装?
将类中的变量、方法隐藏起来,外部无法访问
8.2python中的封装?
在变量或者方法前面加上__
8.3python中的本质
本质是将变量改名为 _类名__变量名,只能在类的内部通过__变量名来使用。

9.反射
9.1什么是反射?
通过字符串来寻找对应的变量或者方法
9.2反射的基本语法
变量 = getattr(类名/对象名/模块名,‘属性的字符串形式’)
9.3反射的实际应用
如6.3中将抽象类时,有一个pay函数

def pay(name,money,kind):
    if kind == 'Alipay':
        obj = Alipay(name)
    elif kind == 'Wechatpay':
        obj = Wechatpay(name)
    obj.pay(money)

我们使用kind来接收支付的类型,但是随着支付类型的增多,我们就要写很多个elif,反射就可以帮我们减少工作量。下面我们通过反射来重写这个pay函数

import sys
def pay(name,price,kind):
    class_name = getattr(sys.modules[__name__], kind)
    obj = class_name(name)
    obj.pay(price)

10.property装饰器
10.1为什么要有property装饰器?

在前面将组合的时候,我们遇到一个问题,我们要查看圆的面积是通过对象名.area()方式,但是area是一个属性,我们习惯用对象名.area来调用,这个时候property就有作用了。

from math import pi
class Circle():
    def __init__(self,r):
        self.r = r

    @property             #装饰的这个方法不能有参数
    def area(self):
        return pi * self.r * self.r

c = Circle(5)
print(c.area)

10.2如何修改、删除被装饰的属性?

class Goods:
    discount = 0.8
    def __init__(self,name,origin_price):
        self.name = name
        self.__price = origin_price
        
    @property
    def price(self):
        return self.__price * self.discount

    @price.setter
    def price(self,new_value):
        if isinstance(new_value,int):
            self.__price = new_value

    @price.deleter
    def price(self):
        del self.__price
apple = Goods('apple',5)
print(apple.price)
apple.price = 'ashkaksk'
del apple.price   # 并不能真的删除什么,只是调用对应的被@price.deleter装饰的方法而已
print(apple.price)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值