面向对象编程(oop),是一种编程方式,这种编程方式需要使用“对象”来实现。这样听起来可能不懂,我借助知乎上面一个例子说明一下。
面向对象是相对于面向过程的,比如你要充话费,你会想,可以下个支付宝,然后绑定银行卡,然后在淘宝上买卡,自己冲,这种种过程。但是对于你女朋友就不一样了,她是面向“对象”的,她会想,谁会充话费呢?当然是你了,她就给你电话,然后你把之前的做了一遍,然后她收到到帐的短信,说了句,亲爱的。这就是面向对象!女的思维大部分是面向“对象”的!她不关心处理的细节,只关心谁可以和结果!
对象是系统中用来描述客观事物的一个实体,它是构成系统的一个基本单位。一个对象由一组属性和对这组属性进行操作的一组服务组成。从更抽象的角度来说,对象是问题域或实现域中某些事物的一个抽象,它反映该事物在系统中需要保存的信息和发挥的作用;它是一组属性和有权对这些属性进行操作的一组服务的封装体。客观世界是由对象和对象之间的联系组成的。
1.世间万物皆对象
2.对象具有唯一性(世界上不存在两片完全相同的叶子)
3.对象具有属性和行为(年龄,身高,会写代码)
4.对象具有状态(比如小李100kg)
5.对象分为分类对象和实例对象两大类
类对象就是具有相同属性和行为的实例对象的抽象,类对象就是实例对象的模板,实例对象是由类对象创建出来的。此外同一类对象的所有实例对象如果具有相同的属性,但是他们的状态可能不一定相同,比如一个班上的小王,小李同学,他们都有一些相同的属性,但这些属性的取值是不同的。
定义类对象的语法格式:
class 类名(object):
#属性与方法
举个例子
其中类名是一个或多个单词组合而成的,单词的首字母需要大写其余字母需要小写。关键字class后面跟着类名,类名通常是大写字母开头的单词,紧接着是(object),表示该类是从哪个类继承下来的。通常,如果没有合适的继承类,就使用object类,这是所有类最终都会继承下来的类。
定义好类我们就可以开始创建实例。
属性也叫描述类具有的属性(比如一个猫颜色,品种,年龄,健康状况)。
class Student(object):
"""__init__ sample."""
def __init__(self, name, score):
self.name = name
self.score = score
__init__方法的第一个参数永远都是self,表示创建实例本身,在__init__方法内部,可以把各种属性绑定到self,因为self指向创建的实例本身。
有了__init__方法,在创建实例的时候,就不能传入空的参数了,必须传入与__init__方法匹配的参数,但self不需要传,Python解释器自己会把实例变量传进去。如下面的类,在新建实例的时候,需要把name和score属性捆绑上去:
In [1]: class Student(object):
...: def __init__(self, name, score):
...: self.name = name
...: self.score = score
...:
In [2]: bart = Student('diggzhang', 99)
In [3]: bart.name
Out[3]: 'diggzhang'
In [4]: bart.score
Out[4]: 99
和普通函数相比,在类中定义的函数只有一点不同,就是第一个参数永远是实例变量self,并且,调用时,不用传递该参数。除此之外,类的方法和普通函数没有什么区别。
方法是定义在类对象中的函数。方法与函数的区别在于:
1.定义方法时,方法的第一个形参表示调用该方法的实例对象,第一个形参的名称是self,也可以是其他名称。
2.调用方法时,系统自动将调用该方法的实例对象作为实参传递给第一个形象,第一个实参会传递给第二个形参,第二个实参会传递给第三个形参,依次类推。
根据类对象创建实例对象的语法格式为:
类名([实参])
面向对象编程的一个重要特点就是数据封装。在上面的Student类中,每个实例就拥有各自的name和score这些数据。我们可以通过函数来访问这些数据,比如打印一个学生的成绩:
def print_socre(std):
print("%s: %s" % (std.name, std.score))
print_socre(bart)
# 实际执行效果
In [7]: def print_socre(std):
...: print("%s: %s" % (std.name, std.score))
...:
In [8]: print_socre(bart)
diggzhang: 99
描述具体的行为,方法也是类中的特殊函数
既然我们创建的实例里有自身的数据,如果想访问这些数据,就没必要从外面的函数去访问,可以在Student类内部去定义这样一个访问数据的函数,这样就把“数据”给封装起来了。这些封装数据的函数和Student类本身关联起来的,我们称之为类的方法:
class Student(object):
def __init__(self, name, score):
self.name = name
self.score = score
def print_socre(self):
print("%s: %s" % (self.name, self.score))
1.在类对象的内部(方法中)
语法格式:self.属性名 = 属性值
推荐在特殊方法__int__中绑定,这样,在创建实例对象后就会自动调用特殊方法__int__对实例对象进行初始化,从而绑定实力属性。如果在其他方法中进行绑定,可能需要手动调用该方法后才会绑定
2.在类对象的外部
Python是动态语言,所以,在实例对象创建之后,可以对其动态地绑定属性。
语法格式:实例对象.属性名 = 属性值
如果指定名称的实例属性已经存在,则是对实例属性进行修改。
类属性就是类对象所拥有的属性,它被所有类对象的实例对象所共有,在内存中只存在一个副本,这个和C++、Java中类的静态成员变量有点类似。对于公有的类属性,在类外可以通过类对象和实例对象访问。
# 类属性
class people:
name="Tom" #公有的类属性
__age=18 #私有的类属性
p=people()
print(p.name) #实例对象
print(people.name) #类对象
# print(p.__age) #错误 不能在类外通过实例对象访问私有的类属性
print(people.__age) #错误 不能在类外同过类对象访问私有的类属性
实例属性
class people:
name="tom"
p=people()
p.age=18
print(p.name)
print(p.age) #实例属性是实例对象特有的,类对象不能拥有
print(people.name)
#print(people.age) #错误:实例属性,不能通过类对象调用