面向对象编程
面向对象-----object oriented programming,简称oop。一个对象包含数据,以及操作数据的函数。
面向对象程序设计把程序视为一组对象的集合,每个对象可以接受其他对象发来的信息,计算机程序的执行就像一系列消息在各个对象之间传递。
在python中,所有数据类型都是对象,可以自定义对象,自定义的对象就是类(calss)。
面向对象的思想是,定义一个对象,定义该对象的属性(变量),定义该对象的方法(函数)。
特点:数据封装, 继承, 多态
创建实例: 类名 + ()
可以自由的给实例绑定属性:
>>> bart.kame = 'B K'
>>> bart.kame
'B K'
可以在创建实例时把我们认为必须的属性强制填写进去
>>> class Student(object):
def __init__(self, name, score):
self.name = name
self.score = score
__init__方法的第一个参数永远是self,指向实例本身。
有了__init__方法,在创建实例的时候就必须传入与__init__方法匹配的参数,但self不需要传。
>>> bart = Student('bart S', 98)
>>> bart.name
'bart S'
>>> bart.score
98
数据封装
可以在对象外编写函数访问对象的实例。也可在Student内部定义访问数据的函数,这就把数据封装起来了。
>>> class Student(object):
def __init__(self, name, score):
self.name = name
self.score = score
def print_score(self):
print '%s: %s' % (self.name, self.score)
>>> bart = Student('bart B', 98)
>>> bart.print_score()
bart B: 98
访问限制
外部代码可以自由修改实例:
>>> bart.score
98
>>> bart.score = 60
>>> bart.score
60
如果想要内部属性不被外部修改,可使把属性前面加入__XXX,如果实例变量名以__开头,就变成了一个私有变量(private)。
这时外部就无法访问了:
>>> class Student(object):
def __init__(self, name, score):
self.__name = name
self.__score = score
def print_score(self):
print '%s: %s' % (self.__name, self.__score)
>>> bart = Student('bart B', 98)
>>> bart.__name
Traceback (most recent call last):
File "<pyshell#36>", line 1, in <module>
bart.__name
AttributeError: 'Student' object has no attribute '__name'
如果要使用__name,与__score的数据怎么办呢:
>>> class Student(object):
def __init__(self, name, score):
self.__name = name
self.__score = score
def print_score(self):
print '%s: %s' % (self.__name, self.__score)
def get_score(self):
return self.__score
def get_name(self):
return self.__name
>>> bart.get_score()
98
如果要修改__score的值呢:
>>> class Student(object):
def __init__(self, name, score):
self.__name = name
self.__score = score
def print_score(self):
print '%s: %s' % (self.__name, self.__score)
def get_score(self):
return self.__score
def get_name(self):
return self.__name
def set_score(self, score):
self.__score = score
>>> bart = Student('bart B', 98)
>>> bart.set_score(60)
>>> bart.get_score()
60
注意: __XXX__ 双下划线的为特殊变量,可以访问
_XXX 单下划线的为约定俗成的私有变量,可以访问但不要访问
将 __name 换成 _Student__name 就可以访问了
>>> bart._Student__name
'bart B'
继承和多态
先有继承,才能有多态。
继承
>>> class Animal(object):
def run(self):
print 'Animal is running'
>>> class Dog(Animal):
pass
Animal是Dog的父类,Dog是Aniaml的子类。
继承的好处之一就是Dog直接继承Animal的方法。
>>> dog = Dog()
>>> dog.run()
Animal is running
如不满意父类的方法,需要彰显Dog的个性,可以在子类中定义父类已有的方法,python在子类中会覆盖父类的方法。
>>> class Dog(Animal):
def run(self):
print 'Dog is running'
def eat(self):
print 'Dog is eating'
>>> dog = Dog()
>>> dog.run()
Dog is running
>>> dog.eat()
Dog is eating
这就叫
多态
我们定义的class,是一种数据类型,与python自带的list, dict,str,没有区别。
多态的好处在于:
>>> def run_twice(animal):
animal.run()
animal.run()
>>> a = Animal()
>>> b = Dog()
>>> run_twice(a)
Animal is running
Animal is running
>>> run_twice(b)
Dog is running
Dog is running
代码运行时,总会调用子类的run()
更甚于:
>>> class Tor(Animal):
def run(self):
print 'Tor is running slowly'
>>> c = Tor()
>>> run_twice(c)
Tor is running slowly
Tor is running slowly
新增一个Animal的子类,对于依赖于Animal为参数的任何方法,都可以不加修改的正常运行。
开闭原则:对扩展开放,对修改封闭
注:任何类,最终都能追溯到根类Object。所以如果没有合适的类继承,就继承自Object类。
获取对象信息
1.type()
判断对象的类型,也可判断出一个变量指向的函数或类。
type返回的还是type类型
>>> type('123')
<type 'str'>
>>> type(123)
<type 'int'>
>>> type(a)
<class '__main__.Animal'>
>>> type(123)==type(456)
True
2. isinstance()
>>> isinstance('a', str)
True
>>> isinstance('a', (str, unicode))
True
3. dir()
可以获得一个对象的所有属性和方法
4. hasatter(), setatter(),getatter()
>>> class MyObject(object):
def __init__(self):
self.x = 9
def power(self):
return self.x * self.x
>>> obj = MyObject()
>>> hasattr(obj, 'x') #是否有属性'x'
True
>>> obj.x
9
>>> hasattr(obj, 'y') #是否有属性'y'
False
>>> setattr(obj, 'y', 19) #设置属性'y'
>>> hasattr(obj, 'y') #是否有属性'y'
True
>>> getattr(obj, 'y') #获取属性'y'
19
除了可以获取属性外,还可获取方法,同上