python面向对象

面向对象

属性查找

1.先从对象的名称空间找

2.再从对象类的类变量找

3.在找父类的类变量

先对象本身-->类-->父类-->父类的父类-->object-->自己定制的元类-->type

class people():
    v_id=0
    def __init__(self,name):
        self.name=name

class zx(people):
    v_id = 1
    def __init__(self,name,v_id):
        super().__init__(name)
        self.v_id=v_id

wl=zx("zx",2)
print(wl.v_id)

2

class people():
    v_id=0
    def __init__(self,name):
        self.name=name

class zx(people):
    v_id = 1
    def __init__(self,name):
        super().__init__(name)

wl=zx("zx")
print(wl.v_id)

1

class people():
    v_id=0
    def __init__(self,name):
        self.name=name

class zx(people):
    def __init__(self,name):
        super().__init__(name)

wl=zx("zx")
print(wl.v_id)

0

继承

类调用方法,和对象调用方法的区别

类调用方法的需要加上self这个形参,但是实例化的对象调用的时候不用填写,因为默认把对象本身作为self这个参数,(这样做有啥好处呢)

class people():
    def hello(self):
        print("hello")

zx=people()
zx.hello()
people.hello("a")

比如,可以这样用,可以使用对象自身的方法属性

class people():
    def __init__(self,age):
        self.age=age
    def chang_age(self,age):
        self.age=age

zx=people(18)
print(zx.age)
zx.chang_age(20)
print(zx.age)

super

在单继承时,super().__init__()people.__init__()是一样的。super()避免了父类的显式调用

class people():
    def __init__(self,name):
        self.name=name

class student(people):
    def __init__(self,name):
        people.__init__(self,name)

zx=student("lalal")
print(zx.name)

lalal

多继承遵从__mro__

多态和多态性

多态

多态指的是一类事物的多种形态

1.序列数据类型有多种形态:字符串,列表,元组

2.动物有多种形态:人,狗,猪

增加了程序的灵活性和可扩展性

多态性

注意:多态与多态性是两种概念

多态性是指具有不同功能的函数可以使用相同的函数名,这样就可以用一个函数名调用不同内容的函数。在面向对象方法中一般是这样表述多态性:向不同的对象发送同一条消息,不同的对象在接收时会产生不同的行为(即方法)。也就是说,每个对象可以用自己的方式去响应共同的消息。所谓消息,就是调用函数,不同的行为就是指不同的实现,即执行不同的函数。(例如len())

接口统一的三种方法

1.abc

python中的抽象基类(ABC,Abstract Base Class)相当于是Java中的接口,抽象基类就是定义各种方法而可以不做具体实现的类,当然也可以实现,只不过子类如果想调用抽象基类中定义的方法需要使用super()

import abc
class people(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def say(self):
        pass

class student(people):
    def say(self):
        print('hello')

zx=student()
zx.say()

hello

2.抛出异常

class people():
    def say(self):
        raise Exception("没有重写方法")

class student(people):
    def say(self):
        pass

zx=student()
zx.say()

3.崇尚鸭子类型:只要走路像鸭子(对象中有某个绑定方法),那你就是鸭子

class student:
    def say(self):
        print("student")

class teacher:
    def say(self):
        print("teacher")

def go_say(self):
    self.say()

zx=student()
zx2=teacher()
go_say(zx)
go_say(zx2)

{'module': 'main', '_zx__tag': 1, 'init': <function zx.init at 0x000001BFFB376D08>, '_zx__hello': <function zx.__hello at 0x000001BFFB376D90>, 'dict': <attribute 'dict' of 'zx' objects>, 'weakref': <attribute 'weakref' of 'zx' objects>, 'doc': None}
{'_zx__name': 'zx125', '_zx__age': 18}

封装

封装数据的主要原因是:保护隐私

封装方法的主要原因是:隔离复杂度(只要知道怎么使用,不需要知道复杂的实现过程)

两个层面的封装

第一个层面

创建类和对象会分别创建二者的名称空间,我们只能用类名.或者obj.的方式去访问里面的名字,这本身就是一种封装

第二个层面

类中把某些属性和方法隐藏起来(或者说定义成私有的),只在类的内部使用、外部无法访问,或者留下少量接口(函数)供外部访问。

python 中的私有

其实说到底还是约定俗成

class zx:
    __tag=1
    def __init__(self,name):
        self.__name=name

    def __hello(self,age):
        self.__age=age

z=zx("zx125")

z._zx__hello(18)

print(zx.__dict__)
print(z.__dict__)

python中的get set

@property

.setter

.deleter

class zx:
    def __init__(self,name,age):
        self.__name=name
        self.age=age

    @property
    def name(self):       #相当于get
        print(self.__name)
    @name.setter          #相当于set
    def name(self,name):
        self.__name=name
    @name.deleter
    def name(self):
        del self.__name

zx125=zx("华盛顿",18)
zx125.name
zx125.name="啊哈哈"
zx125.name
del zx125.name
zx125.name

华盛顿
啊哈哈
print(self.__name)
AttributeError: 'zx' object has no attribute '_zx__name

原文地址:https://www.cnblogs.com/zx125/p/11426132.html