python学习笔记 - day06


面向对象

面向对象的思想就是把事物归类, 标准化
造模子 –>面向对象
根据模子创建新的对象 –> 实例化

例:

  • 下边这个例子已经用了面向对象的思想
    • 部落或联盟创建时, 均遵循BL或者LM方法 –> 规范化
def LM(race, profession, name, hp, att):
    '''
    设定联盟种族,职业,角色名,血量,攻击力
    '''
    dic = {
        'race' = race
        'profession' = profession
        'name' = name
        'hp' = hp
        'att' = att
    }
    def LM_att_BL(BL_name):
        BL_name['hp'] -= dic['att']
        return '%s攻击了%s, 受到了%s伤害, 剩余%sHP' % (dic['name'],BL_name['name'],dic['att'],BL_name['hp'])\
    dic['LM_att_BL'] = LM_att_BL
    return dic

def BL(race, profession, name, hp, att):
    dic = {
        'race' = race
        'profession' = profession
        'name' = name
        'hp' = hp
        'att' = att
    }
    def BL_att_LM(LM_name):
        LM_name['hp'] -= dic['att']
        return '%s攻击了%s, 受到了%s伤害, 剩余%sHP' % (dic['name'],LM_name['name'],dic['att'],LM_name['hp'])
    dic['BL_att_LM'] = BL_att_LM
    return dic

x = LM('DLN','MS',10000,200)
y = BL('XJL','DLY',20000,300)

print(x['LM_att_BL'](y))
print(y['BL_att_LM'](x))

类和对象

对象
相同属性的一类事物, 组成一个类 具体的某一个具有实际属性的个体
抽象概念 具体概念
类是为了描述对象创建的 可以被描述出来
例子:
编程语言 python
人类 马云

类的定义

语法: class 类名:

class X:
    # 静态属性
    a = '静态属性'

    # 动态属性
    def funcA(self):
        return '动态属性'

类的功能

类名虽然可以查看某个方法, 但是一般情况下, 不用类名直接调用方法

1. 属性引用

查看静态属性
print(X.a) # --> '静态属性'
修改静态属性
X.a = '静态属性1'
增加静态属性
X.b = '静态属性2'
删除静态属性
del X.b
使用动态属性, 与调用函数方法一致
print(X.funcA()) # --> '动态属性'
类属性储存的位置
# 除了记录必要的默认值之外, 还记录了类中定义的所有值
print(X.__dict__)

2. 创建对象 –> 实例化

对象 = 类名()

class Person:pass
alex= Person()
实例化过程
  1. 将对象作为第一个参数self, 并将其他参数传给__init__的其他参数, 传给__init__方法,
  2. 自动执行__init__方法中的代码
  3. 自动把self作为返回值, 返回给对象
给对象添加属性
1. 使用__dict__操作
alex.__dict__['name'] = 'alex'
alex.__dict__['age'] = 20
2. 使用 对象名.属性名 操作
alex.name = 'name'
alex.age = 20
3. 使用__init__方法传参
class Person1:
    def __init__(self, name, age):
        self.name = name
        self.age = age

alex = Person1('alex',20)

组合的应用

在一个类中以另外一个类的对象作为数据属性,称为类的组合
描述一种 ‘什么有什么’ 的关系
比如: 圆环内有圆

  • 计算圆环面积
class Circle:
    def __init__(self,r):
        self.r = r
    def s(r):
        return 3.14 * r **2

class Ring:
    def __init__(self,R,r):
        self.C = Circle(R)
        self.c = Circle(r)
    def s(self):
        return self.C.s() - self.c.s()

R = Ring(2,1)
print(R.s())

面向对象的三种状态

继承

新建的类可以继承一个或多个父类
表达一种 ‘什么是什么’ 的关系
比如: 人是动物

名词解释

  1. 父类又可称为基类或超类
  2. 新建的类称为派生类或子类
  3. 单继承, 只有一个父类
  4. 多继承, 有多个父类(python支持, java不支持)

如何继承

# 单继承
class A:pass
class B(A):pass

# 多继承
class A:pass
class B:pass
class C(A,B):pass

调用父类的方法

使用父类名.方法名调用父类方法

参数需要加self

class A:
    def a(self):
        print('is A')
class B(A):
    def b(self ):
        A.a(self)

m = B()
m.b()

# 结果是 'is A'        
使用super()函数调用父类方法

参数不需要加self

class A:
    def a(self):
        print('is A')
class B(A):
    def b(self ):
        super().a()

m = B()
m.b()

# 结果是 'is A'        

继承逻辑

先找对象的内存空间 –> 创建这个对象的类的内存空间 –> 父类的内存空间
1. 创建一个对象
2. 把创建的对象传给__init__
3. 本身没有__init__, 则去找父类的__init__

特殊继承

遵循广度优先算法

钻石继承
class A:pass
class B(A):pass
class C(A):pass
class D(B,C):pass

# 继承顺序 D --> B --> C --> A
乌龟继承
class A:pass
class B(A):pass
class C(A):pass
class D(B):pass
class E(C):pass
class F(D,E):pass

# 继承顺序 F --> D --> B --> E --> C --> A
mro方法

查看向上继承顺序

print(F.mro())

注:
1. 经典类: python3中没有经典类, python2中不主动继承object类的都是经典类, 继承顺序遵循深度优先算法
2. 新式类: python3都是新式类, 新式类继承广度优先算法

多态

python中, 处处都是多态

封装

定义: __属性名, __方法名
隐藏对象的属性和实现细节, 仅对外提供公共访问方式
优点:
1. 隔离变化
2. 便于使用
3. 提高复用性
4. 提高安全箱
原则:
1. 严格区分内外
2. 把不需要对外提供的内容都隐藏起来
3. 把属性都隐藏, 提供公共方法对其访问
实质:
严格意义上仅仅是一种变型操作, __x会自动变为_类名__x进行调用, 所以在子类中定义的__x不会覆盖父类中定义的__x

__funcName –> _className__funcName

class A:
    __M = 0
    def __init__(self):
        self.__N = 1
    def __Foo(self):
        print('from A')
    def bar(self):
        self.__foo()
a = A()
a.bar() 
'''
实际上是执行__Foo方法, 因为__Foo是私有方法, 所以等价于a._A__Foo(), 但是一般禁止这样使用
'''

  • a.test() –> A.test(a) –> a.p() –> B.p(a) –> from B
# 情况1
class A:
    def p(self):
        print('from A')
    def test(self):
        self.p()
class B(A):
    def p(self):
        print('from B')
a = B()
a.test() # --> from B
  • c.test() –> C.test(c) –> c._C__P() –> C._C__P(c) –> from C
# 情况2
class C:
    def __p(self):
        print('from C')
    def test(self):
        self.__p()
class D(C):
    def __P(self):
        print('from D')
c = D()
c.test() # --> from C

关于内存 & 命名空间

class P:
    country = 'china'
    def __init__(self, name):
        self.name = name
alex = P('alex')
  1. py文件 –> 命名空间1
  2. P –> 命名空间2
  3. country & __init__ –> 命名空间3
  4. 执行alex = P(‘alex’), 将对象名alex作为参数传给__init__方法的self参数, 将’alex’传给name参数 –> 命名空间4
  5. 对象名alex –> 命名空间5 –> 指向命名空间4

类对象指针

在创建对象时, 会产生对象和类的联系, 称为类对象指针
对象能通过类对象指针找到类, 但是类不能通过类对象指针找到对象

变量调用

在访问对象属性的时候, 会优先使用自己命名空间内的
如果自己命名空间中没有, 会去类的空间中去找
所以在使用对象修改静态变量的过程中, 相当于在自己的空间中创建了一变量
在操作静态变量的过程中, 推荐使用类.变量名来进行操作

阅读更多
个人分类: Python
上一篇正则表达式
下一篇python学习笔记 - day07
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭