面向对象:属性和方法

私有权限

面向对象三大特性:封装、继承、多态

封装的意义:
  1. 将属性和方法放到一起做为一个整体,然后通过实例化对象来处理;
  2. 隐藏内部实现细节,只需要和对象及其属性和方法交互就可以了;
  3. 对类的属性和方法增加 访问权限控制。
私有权限:在属性名和方法名 前面 加上两个下划线 __
  1. 类的私有属性 和 私有方法,都不能通过对象直接访问,但是可以在本类内部访问;
  2. 类的私有属性 和 私有方法,都不会被子类继承,子类也无法访问;
  3. 私有属性 和 私有方法 往往用来处理类的内部事情,不通过对象处理,起到安全作用。

修改私有属性的值

  • 如果需要修改一个对象的属性值,通常有2种方法

    1. 对象名.属性名 = 数据 ----> 直接修改
    2. 对象名.方法名() ----> 间接修改
  • 私有属性不能直接访问,所以无法通过第一种方式修改,一般的通过第二种方式修改私有属性的值:定义一个可以调用的公有方法,在这个公有方法内访问修改。

多态

所谓多态:定义时的类型和运行时的类型不一样,此时就成为多态 ,多态的概念是应用于Java和C#这一类强类型语言中,而Python崇尚“鸭子类型”。

鸭子类型:虽然我想要一只"鸭子",但是你给了我一只鸟。 但是只要这只鸟走路像鸭子,叫起来像鸭子,游泳也像鸭子,我就认为这是鸭子。

Python的多态,就是弱化类型,重点在于对象参数是否有指定的属性和方法,如果有就认定合适,而不关心对象的类型是否正确。


类属性和实例属性

在了解了类基本的东西之后,下面看一下python中这几个概念的区别

先来谈一下类属性实例属性

在前面的例子中我们接触到的就是实例属性(对象属性),顾名思义,类属性就是类对象所拥有的属性,它被所有类对象实例对象所共有,在内存中只存在一个副本,这个和C++中类的静态成员变量有点类似。对于公有的类属性,在类外可以通过类对象实例对象访问

类属性

class People(object):
    name = 'Tom'  # 公有的类属性
    __age = 12  # 私有的类属性

p = People()

print(p.name)  # 正确
print(People.name)  # 正确
print(p.__age)  # 错误,不能在类外通过实例对象访问私有的类属性
print(People.__age) # 错误,不能在类外通过类对象访问私有的类属性

实例属性(对象属性)

class People(object):
    address = '山东'  # 类属性
    def __init__(self):
        self.name = 'xiaowang'  # 实例属性
        self.age = 20  # 实例属性

p = People()
p.age = 12  # 实例属性
print(p.address)  # 正确
print(p.name)  # 正确
print(p.age)  # 正确

print(People.address)  # 正确
print(People.name)  # 错误
print(People.age)  # 错误

通过实例(对象)去修改类属性

class People(object):
    country = 'china' #类属性


print(People.country)
p = People()
print(p.country)
p.country = 'japan' 
print(p.country)  # 实例属性会屏蔽掉同名的类属性
print(People.country)
del p.country  # 删除实例属性
print(p.country)

总结

  • 如果需要在类外修改类属性,必须通过类对象去引用然后进行修改。如果通过实例对象去引用,会产生一个同名的实例属性,这种方式修改的是实例属性,不会影响到类属性,并且之后如果通过实例对象去引用该名称的属性,实例属性会强制屏蔽掉类属性,即引用的是实例属性,除非删除了该实例属性


静态方法和类方法

1. 类方法

是类对象所拥有的方法,需要用修饰器@classmethod来标识其为类方法,对于类方法,第一个参数必须是类对象,一般以cls作为第一个参数(当然可以用其他名称的变量作为其第一个参数,但是大部分人都习惯以'cls'作为第一个参数的名字,就最好用'cls'了),能够通过实例对象和类对象去访问。

2. 静态方法

需要通过修饰器@staticmethod来进行修饰,静态方法不需要多定义参数,可以通过对象和类来访问。

总结

  1. 从类方法和实例方法以及静态方法的定义形式就可以看出来,类方法的第一个参数是类对象cls,那么通过cls引用的必定是类对象的属性和方法;
  2. 实例方法的第一个参数是实例对象self,那么通过self引用的可能是类属性、也有可能是实例属性(这个需要具体分析),不过在存在相同名称的类属性和实例属性的情况下,实例属性优先级更高。
  3. 静态方法中不需要额外定义参数,因此在静态方法中引用类属性的话,必须通过类实例对象来引用


__new__方法

__new__和__init__的作用

class A(object):
    def __init__(self):
        print("这是 init 方法")

    def __new__(cls):
        print("这是 new 方法")
        return object.__new__(cls)

A()
总结
  • __new__至少要有一个参数cls,代表要实例化的类,此参数在实例化时由Python解释器自动提供

  • __new__必须要有返回值,返回实例化出来的实例,这点在自己实现__new__时要特别注意,可以return父类__new__出来的实例,或者直接是object的__new__出来的实例

  • __init__有一个参数self,就是这个__new__返回的实例,__init____new__的基础上可以完成一些其它初始化的动作,__init__不需要返回值

  • 我们可以将类比作制造商,__new__方法就是前期的原材料购买环节,__init__方法就是在有原材料的基础上,加工,初始化商品环节


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值