面向过程

Procedure-Oriented-Programing,POP
我们之前学的代码是面向过程的。

  1. 把完成某一个需求的所有步骤从头到尾逐步实现
  2. 根据开发需求,将某些功能独立的代码封装成一个个函数
  3. 最后完成的代码,就是顺序地调用不同的函数

面向过程注重 步骤与过程,不注重职责分工,不适合复杂项目的开发。


面向对象

Object-Oriented-Programing,OOP
相比于函数,面向对象是更大的封装,根据 职责 在一个对象中封装多个方法。

拿植物大战僵尸来举例子:


类和对象

是对一群具有相同特征或行为的事物的统称,是抽象的,不能直接使用。
特征 被称为 属性行为 被称为 方法

举例来说, 就相当于制造飞机时的 图纸,是一个 模板,是负责 创建对象 的。对象 就相当于飞机。
用哪一个类创建的对象,这个对象就具有该类的属性和方法。

所以在程序开发中,应该先有类,再有对象。
类只需有一个,对象可以有很多个。不同对象之间的属性可能会不同。


类的设计

在使用面向对象开发前,应该首先分析需求,确定一下程序中需要包含哪些类。
类的三要素:

  • 类名:大驼峰命名法
  • 属性:特征
  • 方法:行为

如:

小明 今年 18 岁身高 1.75,每天早上 完步,会去 东西
小美 今年 17 岁身高 1.65,小美不跑步,小美喜欢 东西

由此可设计出 Person 类:

一只 黄颜色狗狗大黄 ,看见生人 汪汪叫,看见家人 摇尾巴

由此可设计出 Dog 类:


面向对象基础语法

dir

快速确认是否是对象:在 标识符 / 数据 后面输入一个 .,然后按下 Tab 键,如果是对象的话,就会提示该对象常用的方法列表。

使用 dir 可以查看对象内的所有的属性及方法。

__doc__ 方法的使用:

定义简单的类

在一个类中封装多个方法,这样通过这个类创建出来的对象,就可以直接调用这些方法了。
如定义一个只包含方法的类:

class 类名:

    def 方法1(self, 参数列表):
        pass
    
    def 方法2(self, 参数列表):
        pass
  • 类名要符合 大驼峰命名法
  • 在类中定义方法,第一个参数必须是 self

使用类创建对象

对象变量 = 类名()

第一个面向对象程序

小猫 鱼,小猫

class Cat:
    """猫类"""

    def eat(self):
        print("小猫爱吃鱼")

    def drink(self):
        print("小猫要喝水")


tom = Cat()
tom.drink()
tom.eat()

要给对象设置 属性 很简单,只需要在 类的外部的代码 中直接通过 . 设置一个属性即可,如:

tom.name = "Tom"
lazy_cat.name = "大懒猫"

但是不推荐使用,因为对象属性的封装应该封装在类的内部。

self 的使用

由哪一个对象调用的方法,方法内的 self 就是哪一个对象的引用。

class Cat():
  def demo(self):
  print("%s" % self.name)


tom = Cat()
tom.name = "Tom"
tom.demo()

lazy_cat = Cat()
lazy_cat.name = "大懒猫"
lazy_cat.demo()

输出:

Tom
大懒猫

也就是说:

  • 类的外部,通过 变量名. 访问对象的属性和方法
  • 类封装的方法中,通过 self. 访问对象的属性和方法

初始化方法

当使用 类名() 创建对象时,会自动为对象在内存中分配空间,并设置初始值。
初始化方法就是 __init__ 方法,是对象的一种内置方法,该方法在创建对象时会被自动调用:

class Cat:
    def __init__(self):
        print("初始化方法")


tom = Cat()

输出:初始化方法

在初始化方法内部定义属性

__init__ 方法内部使用 self.属性名 = 属性的初始值 就可以定义属性。之后再使用 Cat 类创建的对象,都会拥有该属性。

class Cat:

    def __init__(self):
        self.name = "Tom"


tom = Cat()
print(tom.name)

X = Cat()
print(X.name)

输出:

Tom
Tom

但是这样显然是不太好的,因为所有新定义的对象 name 都是 Tom
所以可以这样改进:

class Cat:

    def __init__(self, name):
        print("初始化方法 %s" % name)
        self.name = name


tom = Cat("Tom")
lazy_cat = Cat("大懒猫")

输出:

初始化方法 Tom
初始化方法 大懒猫

内置方法 __del__

为对象分配完空间后,会自动调用 __init__ 方法。当一个对象被从内存中销毁前,会自动调用 __del__ 方法。这便是一个对象的生命周期。

一个对象的生命周期从调用 类名() 创建开始,一到调用 __del__ 结束。在生命周期内,可以访问对象属性,或者让对象调用方法。

class Cat:

    def __init__(self, new_name):

        self.name = new_name
        print("%s 来了" % self.name)

    def __del__(self):
        print("%s 去了" % self.name)


tom = Cat("Tom")
del tom

输出:

Tom 来了
Tom 去了

内置方法 __str__

使用 print 输出对象变量,默认情况下,会输出:

class Cat:

    def demo(self):
        pass


tom = Cat()
print(tom)

如果希望 print 的内容自定义,就可以利用 __str__ 这个内置方法了(必须返回一个字符串):

class Cat:

    def __init__(self, new_name):

        self.name = new_name

    def __str__(self):

        return "我是小猫 %s" % self.name

tom = Cat("Tom")
print(tom)

输出:我是小猫 Tom