面向对象编程的基本特征

作者:禅与计算机程序设计艺术

1.简介

面向对象的编程(Object-Oriented Programming,OOP)是一种抽象程度很高、编程方式更接近自然语言的方式,具有很强的可维护性和扩展性。OOP的主要特征如下:

抽象化:把现实世界中相似或相关的事物归类到一个集合体中,进而对这个集合体进行操作,提高编程效率和代码的复用性; 继承和多态:子类可以继承父类的属性和方法,并根据需要重写其行为,从而避免代码重复; 封装:隐藏实现细节,仅向外界提供接口,提高代码的可靠性和安全性; 多线程和分布式处理:支持多线程编程,充分利用多核CPU资源,方便开发分布式系统;

2.基本概念

2.1 类(Class)

“类”是对现实世界中某个事物的抽象,它通过数据成员(Data member)和成员函数(Member function)来描述这个事物的特征和行为。比如:狗是一个类,它有四条腿、两只耳朵、尾巴等属性;它也有叫、吃东西等成员函数。

2.2 对象(Object)

对象是类的一个实例或者说具体的个体。比如,我现在有一个小狗,它就是一个“狗”类的一个对象。

2.3 实例变量(Instance variable)

实例变量(instance variable)是定义在类的内部的变量,每个对象都有自己独特的副本。实例变量通常用来存储对象的各项属性值,这些属性值随着对象状态的变化而发生变化。实例变量通过 self 关键字来访问。例如,对于 Dog 类的对象 dog,我们可以这样访问它的 name 属性:dog.name = "Rufus" 。

2.4 类变量(Class variable)

类变量(class variable)是定义在类的外部的变量,所有对象共享该变量的值。类变量可以通过 @classmethod 来访问。例如,我们可以编写 Dog 类来记录狗的数量:

class Dog:
    num_of_dogs = 0

    def __init__(self):
        Dog.num_of_dogs += 1

上面的例子中,Dog 类的 num_of_dogs 是一个类变量,初始值为0。每创建一个 Dog 对象时,num_of_dogs 的值都会增加1。

2.5 方法(Method)

方法(method)是属于类的函数。它用于实现某些功能,并且可以在对象调用。方法通常接受参数(parameter),并返回计算结果。例如:我们定义一个计算两个数之和的方法:

def add(x, y):
    return x + y

我们可以把该方法作为一个成员函数添加到 Dog 类中:

class Dog:
    def __init__(self, name):
        self.name = name

    def bark(self):
        print("Woof!")

    def eat(self, food):
        print("{} is eating {}".format(self.name, food))

my_dog = Dog("Rufus")
print(my_dog)     # Output: <__main__.Dog object at 0x7f9c7e0f6a30>
my_dog.bark()    # Output: Woof!
my_dog.eat("banana")   # Output: Rufus is eating banana

上面示例中,Dog 类有两个方法:init() 和 bark() ,以及一个 eat() 方法。其中,init() 是构造器,用于创建 Dog 对象;bark() 方法用于吠叫,eat() 方法用于吃东西。

2.6 静态方法(Static method)

静态方法(static method)是定义在类上的函数,它不依赖于实例或者类,可以被类自身调用或者直接调用。静态方法通过 @staticmethod 来声明。静态方法可以与普通方法一起共同组成类中的工具方法。

例如,我们可以定义一个静态方法来获取当前日期:

import datetime

class TimeUtils:
    @staticmethod
    def get_current_date():
        now = datetime.datetime.now()
        return now.strftime("%Y-%m-%d")

print(TimeUtils.get_current_date())

上面示例中,TimeUtils 类有一个名为 get_current_date() 的静态方法,它会获取当前日期并以字符串形式返回。我们可以通过类名直接调用该方法。

3.核心算法原理及实现

3.1 堆排序(Heap Sort)

堆排序(Heap Sort)是指利用堆这种数据结构实现的排序算法。堆是一个二叉树,其中每个节点都大于等于(最大堆)或者小于等于(最小堆)其子节点。堆排序首先将待排序序列构建成一个堆,然后再调整堆,使得所得到的序列是一个有序序列。

3.1.1 案例分析

假设有一个长度为 n 的数组 arr,希望按升序排列 arr 中的元素。下面给出堆排序的过程:

  1. 将 arr 看作是一个堆,建立最大堆的过程即用大根堆的性质维护堆的结构。

    a. 从最后一个非叶子结点 k=n/2-1(整除)开始,由下往上依次建立最大堆。 b. 每个结点的左右孩子编号分别为 left=(2k+1), right=(2k+2)。 c. 如果左右孩子存在且比该结点小,则交换它们。

    此时,arr[0]~arr[n/2-1]构成了一颗最大堆。

  2. 对堆进行调整,使之成为一个有序序列。

    a. 把堆顶元素 arr[0] 和堆底元素 arr[n-1] 交换。 b. 把堆的尺寸减小 1,并调用 shift_down(0),重新调整堆。

    c. 在循环中,调用 shift_down(0),使得 arr[i] 小于等于 arr[(2i+1)],并且 arr[i] 小于等于 arr[(2i+2)],然后比较 arr[i] 与 arr[heap_size-1] 交换位置。如果 arr[heap_size-1] 比 arr[i] 大,则停止循环,否则继续执行第 2a、2b 步。

    d. 当堆的尺寸减小到 1 时,排序完成。

时间复杂度:O(nlogn) 。

空间复杂度:O(1) 。

def heap_sort(arr):
    for i in range((len(arr)-2)//2,-1,-1):
        heapify(arr, len(arr), i)

    for j in range(len(arr)-1,0,-1):
        arr[j], arr[0] = arr[0], arr[j]
        heapify(arr, j, 0)

def heapify(arr, size, root):
    largest = root
    left = (root*2)+1
    right = (root*2)+2

    if left < size and arr[left]>arr[largest]:
        largest = left

    if right < size and arr[right]>arr[largest]:
        largest = right

    if largest!= root:
        arr[root], arr[largest] = arr[largest], arr[root]
        heapify(arr, size, largest)

arr = [5, 2, 7, 1, 8, 6, 3]
heap_sort(arr)
print('sorted array:', arr)

输出:

sorted array: [1, 2, 3, 5, 6, 7, 8]

猜你喜欢

转载自blog.csdn.net/universsky2015/article/details/133504823