python 基础十一 面向对象

python是支持面向对象编程的语言

面向对象可以最大限度的支持代码的复用,封装代码,提高代码的可读性。

class Dog(object):
    # 类变量,可以使用类名调用也可以使用实例名调用
    # 使用实例名调用类变量时,若类变量与实例变量名同名时的处理情况是返回实例变量,变量的调用顺序:先搜索实例变量 -->再搜索类变量
    # 作用: 存放所有实例共有的属性,用于节省空间
    num = 112
    name = 'dog Parent'

    def __init__(self, name, weight, age):
        # 这里实例化的变量,都属于对象
        self.name = name # 实例变量又称属性,静态属性
        self.weight = weight
        # 私有变量,外界不可访问
        self.__age = age
        # 实例化对象(初始化一个类),接收相关参数,函数名必须是 __init__
        # 又叫构造函数,在实例化时做一些初始化的工作
        # 对象的构造过程:
        #     1.将传入的变量赋值给对象名,并分配空间
        #     2.建立一个对类中定义方法的引用
        # self是对对象本身的引用,是用来接收实例化时的对象名
        # 实例变量在运行时可以修改
        # self在这里可以看作是一个大字典,可以向里面加入很多内容
        # 类有个属性是 __dict__ 这个字典内存储的就是类的字段,方法,属性
        # 创建一个类,就相当于是在创建一个字典,向里面加入各种属性
        pass

    def __dd(self):
        # 私有方法,同私有变量一样是在前面加 __
        pass

    def bulk(self):
        # 公有方法
        # 类的方法,又称动态属性
        # 方法名任意,是作为对象的方法来使用的
        # self是对对象本身的引用
        # 用于在对象调用方法时将该对象名传给类知道是哪个对象调用这个方法了
        pass

    def f1(self):
        pass
    pass

    def __del__(self):
        # 析构函数
        # 在对象销毁的时候执行某些扫尾操作,如数据库连接关闭,文件关闭
        # 在对象的名称不存在后(del 对象名),python的垃圾回收会将它的空间回收
        # 一般无需自定义
        pass


dog = Dog('dog1', 15, 2)  # 实例,对象
print(dog.name)
print(Dog.name)

# 可以修改实例变量
dog.name = 'dog2'  # 只影响当前实例
Dog.name = 'com'  # 影响所有实例(类变量的修改)
print(dog.name)
print(Dog.name)

# 在这里可以在对象动态添加新属性
# 但这个动态添加的属性只对这一个对象有用
# 也可以动态删除属性,也只对当前对象有效
dog.state = 'ok'





# 类的继承
# 父类中没有的属性 在子类中出现 叫做派生属性
# 父类中没有的方法 在子类中出现 叫做派生方法
# 只要是子类的对象调用,子类中有的名字 一定用子类的,子类中没有才找父类的,如果父类也没有报错
class BigDog(Dog):
    def __init__(self, name, weight, age, home):
        # 子类有新加入的属性,重写父类的构造函数
        # 先要调用父类的构造函数
        # Dog.__init__(name, weight, age) 这样写也可以
        # 推荐下面这样写(新式类写法), 在多继承时方便
        #
        super(BigDog, self).__init__(name, weight, age)
        self.home = home
        pass

    def bulk(self):
        # 重写父类方法
        # 如果不要父类的方法,则进行完全重写,不调用父类的方法
        # 否则应该先调用父类的方法, 类似java继承
        print(self.home)
        pass
    pass

# 子类如果没有加入新的属性,那么子类就不用重写父类的构造函数


bdog = BigDog('cn', 28, 3, 'home2')
bdog.bulk()

# 多重继承
# 继承的顺序
# 1.广度优先搜索(python3 的继承顺序是这种)(新式类,旧式类都是广度)
# 2.深度优先搜索(python2 旧式类是深度,新式类是广度)
# 广度优先搜索 class A(B, C, D): 会依次搜索B,C,D后,找不到再搜索它们的父级

# 多态
# 一种接口多重实现,接口的重用
# 类似java的多态


class A(object):
    def __init__(self):
        self.n = 'A'
    pass


class B(A):
    # def __init__(self):
    #     self.n = 'A'
    pass


class C(A):
    # def __init__(self):
    #     self.n = 'C'
    pass


class D(B, C):
    # def __init__(self):
    #     self.n = 'A'
    pass


obj = D()
print(obj.n)




class Person(object):
    name = 'mankand'

    # @staticmethod 表明这是一个静态方法,它不能调用类变量,也不能调用实例变量,可以通过类名访问也可通过实例变量名访问,推荐使用类名方法访问,如果一个方法与类对象都没有关系就可以指明为@staticmethod
    # 在编写类时有用
    @staticmethod
    def info():
        print('hello, this is earth')

    # 类方法,不需要实例化对象就可以调用
    @classmethod
    def hello(self):
        print('info : %s' % (self.name))


Person.info()
p = Person()
p.info()
p.hello()


# 属性方法的作用就是通过@property把一个方法变成一个静态属性
#   有时候只能使用这个方法将对象的多个字段组成一条信息
# 对静态属性的修改 @属性名.setter
# 对静态属性的删除 @属性名.deleter


class Student(object):
    def __init__(self, name='default', age=18, sex='男'):
        self.__name = name
        self.__age = age
        self.__sex = sex
        pass

    @property  # 把一个方法变为一个静态属性
    def info(self):
        return '%s %s %s' % (self.__name, self.__age, self.__sex)
        pass

    @info.setter  # 修改
    def info(self, tu):
        self.__name = tu[0]
        self.__age = tu[1]
        self.__sex = tu[2]
        pass

    @info.deleter  # 删除
    def info(self):
        del self.__name
        del self.__age
        del self.__sex
        pass


s1 = Student()
print(s1.info)
s1.info = 'mfkcel', 25, 'male'
print(s1.info)
del s1.info


# 类中特殊成员方法
# 1. __doc__  表示类的描述信息

class Foo:
    """ 描述类信息,这是用于看片的神奇 """
    def func(self):
        pass


# 描述信息是属于类的,不属于对象
print(Foo.__doc__)




# 2. __module__ 表示当前操作的对象在哪个模块
#   __class__     表示当前操作的对象的类是什么
print(p.__class__)
print(p.__module__)


# 3. __call__ 对象后面加括号,触发执行
#    构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()
class Foo1:

    def __init__(self):
        pass

    def __call__(self, *args, **kwargs):
        print('__call__')


obj = Foo1()  # 执行 __init__
obj()  # 执行 __call__

# 4. __dict__ 查看类或对象中的所有成员


class Province:
    country = 'China'

    def __init__(self, name, count):
        self.name = name
        self.count = count

    def func(self, *args, **kwargs):
        print('func')


# 获取类的成员,即:静态字段、方法、
print(Province.__dict__)
# 输出:{'country': 'China', '__module__': '__main__', 'func': <function func at 0x10be30f50>, '__init__': <function __init__ at 0x10be30ed8>, '__doc__': None}

obj1 = Province('HeBei', 10000)
print(obj1.__dict__)
# 获取 对象obj1 的成员
# 输出:{'count': 10000, 'name': 'HeBei'}

obj2 = Province('HeNan', 3888)
print(obj2.__dict__)
# 获取 对象obj1 的成员
# 输出:{'count': 3888, 'name': 'HeNan'}

# 7.__str__ 如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值。
# 相当于java中的toString()方法


class Foo3:

    def __str__(self):
        return 'mfkcel'


obj = Foo3()
print(obj)
# 输出:mfkcel

# _9._getitem__、__setitem__、__delitem__
# 用于索引操作,如字典。以上分别表示获取、设置、删除数据


class Foo4(object):

    def __getitem__(self, key):
        print('__getitem__', key)

    def __setitem__(self, key, value):
        print('__setitem__', key, value)

    def __delitem__(self, key):
        print('__delitem__', key)


obj = Foo4()

result = obj['k1']  # 自动触发执行 __getitem__
obj['k2'] = 'mfkcel'  # 自动触发执行 __setitem__
del obj['k1']

# 类的创建方式需要掌握

# 反射
# 通过字符串映射或修改程序运行时的状态、属性、方法, 有以下4个方法

class Foo5(object):

    def __init__(self):
        self.name = 'mfkcel'

    def func(self):
        return 'func'


obj = Foo5()

# #### 检查是否含有成员 ####
hasattr(obj, 'name')
hasattr(obj, 'func')

# #### 获取成员 ####
getattr(obj, 'name')
getattr(obj, 'func')

# #### 设置成员 ####
setattr(obj, 'age', 18)
setattr(obj, 'show', lambda num: num + 1)

# #### 删除成员 ####
#  操作的是当前对象
delattr(obj, 'name')
delattr(obj, 'func')



# java : 面向对象编程
# 设计模式   —— 接口
# 接口类 : python原生不支持
# 抽象类 : python原生支持的
# abc模块中的metaclass = ABCMeta,@abstructmethod
# 本质是做代码规范用的,希望在子类中实现和父类方法名字完全一样的方法
from abc import abstractmethod,ABCMeta
class Payment(metaclass=ABCMeta):  # 元类 默认的元类 type
    @abstractmethod
    def pay(self,money):pass   # 没有实现这个方法
# 规范 :接口类或者抽象类都可以
# 接口类 支持多继承,接口类中的所有的方法都用实现
# 抽象类 不支持多继承,抽象类中方法可以实现
class Wechat(Payment):
    def pay(self,money):
        print('已经用微信支付了%s元'%money)

class Alipay(Payment):
    def pay(self,money):
        print('已经用支付宝支付了%s元' % money)

class Applepay(Payment):
    def pay(self,money):
        print('已经用applepay支付了%s元' % money)

def pay(pay_obj,money):  # 统一支付入口
    pay_obj.pay(money)

wechat = Wechat()
ali = Alipay()
app = Applepay()
wechat.pay(100)
ali.pay(200)
p = Payment()


# 接口类支持多继承
from abc import abstractmethod,ABCMeta
class Swim_Animal(metaclass=ABCMeta):
    @abstractmethod
    def swim(self):pass

class Walk_Animal(metaclass=ABCMeta):
    @abstractmethod
    def walk(self):pass

class Fly_Animal(metaclass=ABCMeta):
    @abstractmethod
    def fly(self):pass

class Tiger(Walk_Animal,Swim_Animal):
    def walk(self):
        pass
    def swim(self):
        pass
class OldYing(Fly_Animal,Walk_Animal):pass
class Swan(Swim_Animal,Walk_Animal,Fly_Animal):pass


#一切皆文件
import abc #利用abc模块实现抽象类

class All_file(metaclass=abc.ABCMeta):
    all_type='file'
    @abc.abstractmethod #定义抽象方法,无需实现功能
    def read(self):
        '子类必须定义读功能'
        with open('filaname') as f:
            pass

    @abc.abstractmethod #定义抽象方法,无需实现功能
    def write(self):
        '子类必须定义写功能'
        pass

class Txt(All_file): #子类继承抽象类,但是必须定义read和write方法
    def read(self):
        print('文本数据的读取方法')
    def write(self):
        print('文本数据的读取方法')

class Sata(All_file): #子类继承抽象类,但是必须定义read和write方法
    def read(self):
        print('硬盘数据的读取方法')

    def write(self):
        print('硬盘数据的读取方法')

class Process(All_file): #子类继承抽象类,但是必须定义read和write方法
    def read(self):
        print('进程数据的读取方法')

    def write(self):
        print('进程数据的读取方法')

wenbenwenjian=Txt()

yingpanwenjian=Sata()

jinchengwenjian=Process()

#这样大家都是被归一化了,也就是一切皆文件的思想
wenbenwenjian.read()
yingpanwenjian.write()
jinchengwenjian.read()

print(wenbenwenjian.all_type)
print(yingpanwenjian.all_type)
print(jinchengwenjian.all_type)


# 抽象类 : 规范
# 一般情况下 单继承 能实现的功能都是一样的,所以在父类中可以有一些简单的基础实现
# 多继承的情况 由于功能比较复杂,所以不容易抽象出相同的功能的具体实现写在父类中


# python
# python中没有接口类  :
  #  python中自带多继承 所以我们直接用class来实现了接口类
# python中支持抽象类  : 一般情况下 单继承  不能实例化
  #  且可以实现python代码

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值