2018-12-17面向对象总结

面向对象总结


面向对象(oop)

  类:抽象概念,类型,是对一群具有相同特征或者行为的事物的一个统称,是抽象的,不能直接使用

  对象:实际物体,类实例化对象,由类创建出来的一个具体存在

  属性:

    描述类   :  类属性

    描述对象 : 实例属性

  行为:被称为方法

类和对象的关系

对象是根据类创建出来的,先有类,再有对象

类只有一个,而对象可以有很多个

类中定义了什么属性一和方法,对象中就有什么属性和方法,不可能多,也不可能少

定义类:

    class 类名:

      def 方法1 (self , 参数列表):

      pass

      def 方法1 (self , 参数列表):

      pass

创建对象:

    对象变量= 类名()

初始化:对象变量.方法1()

       对象变量.方法2()

私有属性和私有方法:

私有属性和方法就是对象不希望公开的属性和方法,只希望在对象的内部被使用

定义属性或方法时,在属性名或方法名前,增加两个下划线,定义的就是私有属性或方法   私有属性和方法,外部不能直接访问到

例如:

  class  Women:

    def __init __(self,name):

      self.name = name 

      self.__age = 18

    def __secret(self):

      print(self.__age)

s1=Women()

print(s1.secret())

私有属性:解释器做了名字的修改

print(s1.Women__age)

私有方法:

s1.Women__secret()

继承:

继承分为:单继承和多继承

单继承:子类拥有父类的所有方法和属性

子类继承自父类,可以直接享受父类中已经封装好的方法,不需要再次开发

子类中应该根据职责,封装子类特有的属性和方法

继承的语法:

class 类名 (父类名):

  pass

例如:class A :

      pass

    class B(A)

      pass

继承的传递性:

c类从b类继承,b类又从a类继承,那么c类就具有b类和a类的所有属性和方法

子类拥有父类以及父类的父类中封装的所有属性和方法

多继承:

子类可以拥有多个父类,并且具有所有父类的属性和方法

语法:

class 子类名(父类名1,父类名2)

  pass

mro:查看方法搜索顺序,主要用于多继承时判断方法,属性的调用路径

在搜索方法时,是按照 __mro__ 的输出结果 从左至右 的顺序查找的

如果在当前类中 找到方法,就直接执行,不再搜索

如果 没有找到,就查找下一个类 中是否有对应的方法,如果找到,就直接执行,不再搜索

如果找到最后一个类,还没有找到方法,程序报错

多态:

多态是不同的子类对象,调用相同的父类方法,产生不同的执行结果

多态可以增加代码的灵活度

 

class Animal(object):
    def run(self):
        print('animal is running')


class Dog(Animal):
    def run(self):
        print('Dog run fast')


class Rabbit(Animal):
    def run(self):
        print('Rabbit jump...')

class Cat(Animal):
    pass

class Timer(object):
    def run(self):
        print('the time is running')


# 多态:同一种类型,不同的表现形式
def runTwice(animal):
    animal.run()
    animal.run()

a = Animal()
rabbit = Rabbit()

runTwice(a)
runTwice(rabbit)

# 鸭子类型
tm = Timer()
runTwice(tm)

 

限制实例属性:

__slots__=("name", "age")#只允许由”name“ ,”age“ 属性

修饰器:

@property 可以直接获取值 ,可以单独存在

设置器:

@score。setter,不单独存在,一定要有property

class Person(object):
    __slots__ = ('name', 'age') # 只允许由'name' 'age'属性
'''
per1 = Person()
per1.name = '小明'
print(per1.name)
per1.height = 167 # 不允许
'''

class Student(object):
    def __init__(self, age):
        self.__age = age
    '''
    def setScore(self, score):
        if 0 <= score <= 100:
            self.__score = score
            return 'ok'
        else:
            return 'error'
            
    def getScore(self):
        return self.__score
    '''

    @property # 访问器 可以单独存在
    def score(self):
        print('getter is called')
        return self.__score

    @score.setter # 设置器 不单独存在,一定要有property
    def score(self, score):
        print('setter is called')
        if 0 <= score <= 100:
            self.__score = score
            return 'ok'
        else:
            return 'error'

    @ property
    def age(self):
        return self.__age


s1 = Student(20)
'''
if s1.setScore(10) == 'ok': # s1.score= 100
    print(s1.getScore())
'''
s1.score = 100
print(s1.score)
print(s1.age

魔法方法:

__str__:打印本类的对象时,自动调用

__repr__:在解释器环境下直接输出本对象,自动调用方法

__iter__:返回可迭代的对象,

__next__:随着打循环自动调用

__len__:调用本类对象时候自动调用方法

___getitem__:索引时自动调用的方法

__call__:调用本类对象的时候自动调用方法

class WWW:
    def __str__(self):
        return"123456"
    def __repr__(self):
        return self.__str__()
    def __len__(self):
        return 99
    def __call__(self, *args, **kwargs):
        print(self.__str__())

print(dir(WWW))

S = WWW()
print(S)

print(len(S))
S()


class QQQ:
    cnt=0
    def __init__(self):
        self.a = 0
        self.b = 1
    def __iter__(self):
        return self
    def __next__(self):
        self.a , self.b = self.b, self.a+self.b
        # __iter__ 与 __next__ 缺一不可

        if self.a >=1000:
            raise StopIteration
        QQQ.cnt +=1
        return self.a
    def __len__(self):
        return QQQ.cnt

    def __getitem__(self,n):
        if isinstance(n , int):
            a,b = 0,1
            while n >= 0:
                a,b = b, a+b
                n -=1
            return a
        if isinstance(n,slice):
            if n.start == None:
                start = 0
            else:
                start = n.start
            if n.stop == None:
                return "error"
            stop = n.stop
            l = []
            for i in range(start,stop):
                l.append(self[i])
            return l


w = QQQ()
for i in w:
    print(i ,end=" ")
print()

print(len(w))

for i in w:
    print(i , end="")
print()
print(w[2:4])

枚举:

INSERT=1 缺点就是本质变量,不可以改变

unique 防止枚举成员的得复

from enum import Enum,unique

@ unique
class Menu(Enum):
    INSERT = 1
    DELETE = 2
    UPDATE = 3
    SHOW = 4

print(Menu.DELETE.value==2)
print(Menu.DELETE.value)
print(Menu["INSERT"])

 元类

mataclass指定用什么模版

tpye:构建一个类

__new__:构建类时自动调用方法

class Test(object):
    def show(self, name='python'):
        print('hello %s', name)
'''

# type()构建一个类

def f(self, name='python'):
    print('hello %s'% name)

Test = type('Test', (object,), dict(show=f))

t = Test()
t.show()

# 另一种构建类的方法,是先构建元类,以元类为模板构建类
class ListMetaclass(type):
    def __new__(cls, name, bases, attrs):
        '''类方法'''
        attrs['add'] = lambda self, value : self.append(value)
        return type.__new__(cls, name, bases, attrs)

class Mylist(list, metaclass=ListMetaclass):
    pass

l = Mylist()
print(type(l))
l.add(1)
l.add('hello')
print(l
原文地址:https://www.cnblogs.com/youmeishaoye/p/10133722.html