前言:

因为没有系统学习过python语言,所以在看python代码的过程中十分吃力,因此决定把每次不懂的地方记录之,积土成山,积水成渊。


面向对象(OOP)


面向对象编程——Object Oriented Programming(OOP);一种程序设计思想。OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数


计算机程序是一组对象的集合,而每个对象都可以接收其他对象发过来的消息,并处理这些消息,计算机程序的执行就是一系列消息在各个对象之间传递。

举例Student对象

  • 对象的属性——比如学生name和score的两个属性
  • 对象的方法——给对象发消息实际上就是调用对象对应的关联函数,我们称之为对象的方法(Method)
#Student对象
class Student(object):
#Students对象拥有的两个属性(Property)
def __init__(self, name, score):
self.name = name
self.score = score
#对象的方法
def print_score(self):
print('%s: %s' % (self.name, self.score))

使用面向对象的程序写出结果。

#Bart Simpson,Lisa Simpson是两个具体的对象,是实例()
bart = Student('Bart Simpson', 59)
lisa = Student('Lisa Simpson', 87)
bart.print_score()
lisa.print_score()

类和实例

Class——比如Student,有模板的作用;

实例

Instance,由类创造出来的具体的对象,每个对象拥有相同的方法。

__Init__方法
class Student(object):

def __init__(self, name, score):
self.name = name
self.score = score

第一个参数永远是self,表示创建的实例本身,可以把各种属性绑定到self上。有了__init__方法,在创建实例的时候,就不能传入空的参数了,必须传入与__init__方法匹配的参数但self不需要传,Python解释器自己会把实例变量传进去。

#不能传入空参数,匹配
>>> bart = Student('Bart Simpson', 59)
>>> bart.name
'Bart Simpson'
>>> bart.score
59
方法定义与调用

除了第一个参数是self外,其他和普通函数一样。要调用一个方法,只需要在实例变量上直接调用,除了self不用传递,其他参数正常传入。

class Student(object):

def __init__(self, name, score):
self.name = name
self.score = score
#第一个参数是self
def print_score(self):
print('%s: %s' % (self.name, self.score))
>>> bart.print_score()
Bart Simpson: 59

访问限制

在Class内部,有属性和方法,可以自由地修改一个实例的​​name​​​、​​score​​属性;如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__​。在Python中,实例的变量名如果以__开头,就变成了一个私有变量(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 Simpson', 59)
>>> bart.get_name()
'Bart Simpson'
>>> bart.__name = 'New Name' # 设置__name变量!
>>> bart.__name
'New Name'

表面上看,外部代码“成功”地设置了__name变量,但实际上这个__name变量和class内部的__name变量不是一个变量!内部的__name变量已经被Python解释器自动改成了_Student__name,而外部代码给bart新增了一个__name变量。

>>> bart.get_name() # get_name()内部返回self.__name
'Bart Simpson'

具体参考:​​廖雪峰python访问限制教程​

面向对象的三大特点:数据封装、继承、多态

数据封装

在Student类中,每个实例就拥有各自的name和score这些数据,可以通过函数来访问这些数据,没有必要从外面的函数去访问,可以直接在Student类的内部定义访问数据的函数,这样,就把“数据”给封装起来了。

继承
什么是继承?

当定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class)。

class Animal(object):
def run(self):
print('Animal is running...')
继承举例

注意写法——新的一个类名括号里加入父类,即继承父类的所有。

class Dog(Animal):
pass

class Cat(Animal):
pass
继承的好处

1.子类获得了父类的全部功能,自动拥有了​​run()​​​方法。

dog = Dog()
dog.run()

cat = Cat()
cat.run()

运行结果如下:

Animal is running...
Animal is running...

2.同样可以对子类加入一些其他的方法,并且可以对父类的代码进行我们需要的改进。(见下面run方法)——引出多态

class Dog(Animal):
#继承了父类的run,可以进行相应的改进
def run(self):
print('Dog is running...')

def eat(self):
print('Eating meat...')

此时改进后的run方法,再次运行结果如下。

Dog is running...

即:

当子类和父类都存在相同的run()方法时,子类的run()了父类的run(),在代码运行的时候,总是会调用子类的run()。——多态!

多态

调用方只管调用,不管细节,当新增一种比如​​Animal​​​的子类时,只要确保​​run()​​方法编写正确,不用管原来的代码是如何调用的。



未完待续...


参考文章:

推荐python学习网站:​​廖雪峰Python教程​