面向对象
不了解什么是面向对象,就无法更好的掌握python
Python既支持面向过程的编程也支持面向对象的编程。
面向过程:程序是由过程或仅仅是可重用代码的函数构建起来的。
面向对象:程序是由数据和功能组合而成的对象构建起来的。
面向对象中两个重要的概念是类和对象。
类是对事物的抽象,比如说”人类”.对象是具体的事物。比如具体的某个”人”
何谓类?
在了解类之前,先回顾下初学python时的一句非常重要的话
一切皆对象。
那么是什么是pythong中的对象呢?
Every object has an identity, a type and a value.
官方文档里面有这样一句话,说python中的每个对象都有一个
id
type
value
所以我们常用的字符串,列表等都是对象
在python中,把具有相同属性和方法的对象归为一个类(class)
class Person():
# 我们每一个人都是一个对象,我们具有相同属性和方法所以归为人"类"
# 这个类拥有的静态字段为star,静态字段可以由类来直接进行访问,比如Person.star
# 拥有的普通方法为 introdece_self,包含有一个self,因为这个self将会在调用该方法的时候,把调用的对象返回给self,然后就可以使用这个对象的字段了,比如self.name
star = "Earth"
def __init__(self,name,age):
# 构造方法,初始化实例的时候执行
self.name = name
self.age = age
def introduce_self(self):
#人类所拥有的一个方法
print "My name is %s ,my age is %s"%(self.name,self.age)
# 类的属性 (还有其他定义类的属性的方法)
@property
def attr_p(self):
return "This is a Class attr"
# 类的属性调用的时候不用加括号。
# 类的普通方法调用的时候需要加上括号。
类的特性
继承 封装 多态
继承
从字面意思上来讲就是从基类得到某些东西。
比如上面的”人类”可以是从”动物类”继承某些属性。
class Animals():
# 动物类
pass
class Person(Animals):
# 从动物类继承的人类
# 继承之后,可以使用基类的方法和属性。
以上只是简单的单继承,但是python中支持多继承哦。
#python中有两种类
#经典类
class Per:
pass
# 新式类,新式类继承object
class new(object):
pass
# 经典类和新式类在多继承的时候有一点点区别。
比如经典类
class A:
def show():
print "A"
class B(A):
def show():
print "B"
class C():
def show():
print "C"
class D(B,C):
pass
d1=D()
# 在这里D类继承了B和C,B又继承了A。A B C里面都有show方法。
# 当调用show方法的时候,先按照继承顺序,先从B里面找。B里面如果没有,那么找A里面。A如果没有再找C里面。这叫深度优先。
# 新式类
class A(object):
def show():
print "A"
class B(A):
def show():
print "B"
class C(A):
def show():
print "C"
class D(B,C):
pass
d2 = D()
# 上面的是新式类的范例。当B C都继承自一个新式类A。D继承了B C.按照继承顺序,如果D要找一个方法,先去B里面找。如果B里面没有,再去C里面找。C里面如果没有再去A里面找。这叫广度优先。(注意,C必须和D一样继承A类才适用广度优先)
多态
多态也可以从”动物类”和”人类”这来举例,
比如动物原来的某个属性,到”人类”就已经发生变化(变异),
最终”人类”可以保持自己的多样性.
封装
面向对象的封装来说,其实就是使用构造方法将内容封装到 对象 中,然后通过对象直接或者self间接获取被封装的内容。
封装是面向对象中非常重要的内容
封装就是把内容封起来,然后再去调用。
class Person(object):
def __init__(self,name,age):
self.name = name
self.age = age
def show(self):
print self.name
print self.age
# 比如上面这个类就是把name和age封装起来了。
# 调用的时候可以直接用实例化的对象来调用
# 也可以通过self来调用。show方法就是用self来调用封装的内容的。
面向对象之 self
# 还是用上面这个例子来说
class Person(object):
def __init__(self,name,age):
self.name = name
self.age = age
def show(self):
print self.name
print self.age
p1 = Person("hansz",22)
# 上面的例子定义了一个类Person,并且实例化了一个对象p1
# 我们来看定义类的时候,首先继承object。是新式类。
# 然后定义构造方法。注意构造方法的三个参数。第一个self。
# self的意思是自己。当实例化对象的时候,构造方法传进来的self是对象自己。构造方法就相当于p1.name="hansz" p1.age=22
# 下面的show方法之所以要传入self。是因为他传入之后就可以直接使用对象的属性了。print p1.name
类成员
字段
首先是字段,类里面的字段分为静态字段和普通字段。
静态字段 是属于类的 在内存中只有一份
普通字段 是属于对象的 每个对象都有一份
比如
class city(object):
province = "甘肃"
def __init__(self,city_name):
self.city_name = city_name
wuwei = city("武威")
# 上面这个类里面province 是类的字段。也就是静态字段。是可以直接通过类访问的。比如city.province 当然,也可以通过对象来访问。wuwei.province
方法
普通方法
之前说的都是普通方法。
类方法 和 静态方法
类方法,和静态字段一样,是直接可以用类来调用的。
静态方法,由类调用,无默认参数。
class A(object):
def test():
pass
@classmethod
def class_m(cls):
# 至少有一个cls参数。
print "this is a class method ."
@staticmethod
def static_m():
print "This is a static method"
# 上面写了一个简单的类方法 和静态方法
# 实现类方法和静态方法需要python语法糖@ 。也就是装饰器。
方法调用者不通,调用时传入的参数不同,
属性
class A:
def func(self):
pass
# 定义属性
@property
def prop(self):
pass
# 实例化对象
foo_obj = Foo()
foo_obj.func()
foo_obj.prop #调用属性
# 属性可以看作是方法的一种,但是属性调用的时候,又不用加括号。
# 属性存在意义是:访问属性时可以制造出和访问字段完全相同的假象
属性的两种定义方式