Python面向对象编程

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

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

  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))

面向对象的设计思想是从自然界中来的,因为在自然界中,类(Class)和实例(Instance)的概念是很自然的。Class是一种抽象概念,比如我们定义的Class——Student,是指学生这个概念,而实例(Instance)则是一个个具体的Student。

一、定义类

  class Student(object):
        pass

class后面紧接着是类名,即Student,类名通常是大写开头的单词,紧接着是(object),表示该类是从哪个类继承下来的,通常,如果没有合适的继承类,就使用object类,这是所有类最终都会继承的类。

由于类可以起到模板的作用,因此,可以在创建实例的时候,把一些我们认为必须绑定的属性强制填写进去。通过定义一个特殊的__init__方法,在创建实例的时候,就把属性绑上去(相当于Java的构造函数)

  class Student(object):

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

注意到__init__方法的第一个参数永远是self,表示创建的实例本身,因此,在__init__方法内部,就可以把各种属性绑定到self,因为self就指向创建的实例本身。

二、创建实例

创建实例是通过类名+()实现的

  bart = Student()

三、封装

面向对象编程的一个重要特点就是数据封装。

方法就是与实例绑定的函数,和普通函数不同,方法可以直接访问实例的数据。

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

四、访问限制

如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__,在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))

改完后,对于外部代码来说,没什么变动,但是已经无法从外部访问实例变量.__name实例变量.__score

Python本身没有任何机制阻止你干坏事,一切全靠自觉。

五、继承

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

继承有什么好处?最大的好处是子类获得了父类的全部功能

在继承关系中,如果一个实例的数据类型是某个子类,那它的数据类型也可以被看做是父类。但是,反过来就不行

六、多态

多态真正的威力:调用方只管调用,不管细节,而当我们新增一种Animal的子类时,只要确保run()方法编写正确,不用管原来的代码是如何调用的。这就是著名的“开闭”原则:

对扩展开放:允许新增Animal子类;

对修改封闭:不需要修改依赖Animal类型的run_twice()等函数。

七、静态语言VS动态语言

对于静态语言(例如Java)来说,如果需要传入Animal类型,则传入的对象必须是Animal类型或者它的子类,否则,将无法调用run()方法。

对于Python这样的动态语言来说,则不一定需要传入Animal类型。我们只需要保证传入的对象有一个run()方法就可以了

这就是动态语言的“鸭子类型”,它并不要求严格的继承体系,一个对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子。

Python的“file-like object“就是一种鸭子类型。对真正的文件对象,它有一个read()方法,返回其内容。但是,许多对象,只要有read()方法,都被视为“file-like object“。许多函数接收的参数就是“file-like object“,你不一定要传入真正的文件对象,完全可以传入任何实现了read()方法的对象。

八、获取对象信息

(1)判断对象类型

判断对象类型,使用type()函数

判断class的类型,可以使用isinstance()函数

(2)获得一个对象的所有属性和方法

  >>> dir('ABC')
  ['__add__', '__class__',..., '__subclasshook__', 'capitalize', 'casefold',..., 'zfill']

(3)直接操作一个对象的状态

  getattr()、setattr()以及hasattr()

九、实例属性和类属性

(1)实例属性
由于Python是动态语言,根据类创建的实例可以任意绑定属性。

给实例绑定属性的方法是通过实例变量,或者通过self变量:

class Student(object):
def init(self, name):
self.name = name

s = Student('Bob')
s.score = 90

(2)类属性

直接在class中定义属性,这种属性是类属性,归Student类所有:

class Student(object):
name = 'Student'

当我们定义了一个类属性后,这个属性虽然归类所有,但类的所有实例都可以访问到。

编写程序的时候,千万不要对实例属性和类属性使用相同的名字,因为相同名称的实例属性将屏蔽掉类属性,但是当你删除实例属性后,再使用相同的名称,访问到的将是类属性。

博客内容用于记录自己学习后的收获,如有侵权请联系我删除
原文地址:https://www.cnblogs.com/ptxiaochen/p/13634240.html