• 面向对象编程基础:封装、继承、多态与抽象的全面解析


    面向对象的三大特征

    面向对象编程有三大特征:封装、继承和多态。

    • 封装(Encapsulation):封装确保对象中的数据安全,通过将数据和操作数据的方法封装在一个对象中,避免外部直接访问对象的数据。
    • 继承(Inheritance):继承保证了对象的可扩展性,子类可以继承父类的属性和方法,并且可以在此基础上进行扩展。
    • 多态(Polymorphism):多态保证了程序的灵活性,允许不同类型的对象对于相同的消息作出不同的响应。

    面向对象编程基础之类与对象

    在面向对象编程中,我们通常会定义类(Class)和对象(Object)。类是对一类相似对象的抽象描述,而对象则是具体的实例。下面让我们来了解一下类和对象的概念以及它们之间的关系。

    定义一个类

    class A(object):
    
        # 类属性
        count = 0
    
        def __init__(self):
            # 实例属性
            self.name = '孙悟空'
    
        def test(self):
            # 实例方法
            print('这是test方法~~~', self)
    
        @classmethod            
        def test_2(cls):
            # 类方法
            print('这是test_2方法,他是一个类方法~~~', cls)
            print(cls.count)
    
        @staticmethod
        def test_3():
            # 静态方法
            print('test_3执行了~~~')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    在上述代码中,我们定义了一个类A。其中:

    • count是类属性,可以通过类或实例访问,只能通过类对象修改。
    • __init__()是构造方法,用于初始化实例属性,创建对象时自动调用。
    • test()是实例方法,以self作为第一个参数,操作实例属性。
    • test_2()是类方法,以cls作为第一个参数,操作类属性。
    • test_3()是静态方法,不需要指定默认参数,与当前类无关。

    创建对象并调用方法

    a = A()
    
    a.test()
    
    A.test_2()
    
    A.test_3()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在上述代码中,我们创建了一个对象a,然后通过实例对象调用了实例方法test()。接着,我们通过类对象调用了类方法test_2()和静态方法test_3()

    这就是类与对象的基本概念和使用方式。接下来,我们将继续探讨面向对象编程中的其他特性。

    面向对象编程基础之继承和多态

    在面向对象编程中,继承和多态是两个重要的概念,它们能够提高代码的复用性和灵活性。让我们一起来学习一下继承和多态的用法和特点。

    继承

    继承是面向对象编程中的一种机制,它允许我们创建一个新的类,该类可以继承自一个或多个已存在的类。被继承的类称为父类(或基类),新创建的类称为子类(或派生类)。子类继承了父类的属性和方法,并可以在此基础上进行扩展和修改。

    # 定义一个父类
    class Parent(object):
        def __init__(self):
            self.parent_attr = '父类属性'
    
        def parent_method(self):
            print('这是父类方法')
    
    # 定义一个子类,继承父类
    class Child(Parent):
        def __init__(self):
            # 调用父类的构造方法
            super().__init__()
            self.child_attr = '子类属性'
    
        def child_method(self):
            print('这是子类方法')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    在上述代码中,我们定义了一个父类Parent和一个子类Child。子类Child继承了父类Parent,并通过super().__init__调用了父类的构造方法,以获得父类的属性和方法。子类可以在此基础上添加自己的属性和方法。

    多态

    多态是面向对象编程中一个非常强大的特性。它允许我们使用父类的引用来指向子类的对象,从而实现灵活的代码设计。通过多态,我们能够以统一的方式处理不同的子类对象。

    # 使用多态调用父类方法
    def invoke_method(obj):
        obj.parent_method()
    
    # 创建父类和子类对象
    parent = Parent()
    child = Child()
    
    # 调用父类方法
    invoke_method(parent)
    invoke_method(child)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在上述代码中,我们定义了一个invoke_method函数,它接受一个父类对象作为参数,并调用了父类的方法。然后,我们创建了一个父类对象parent和一个子类对象child,并将它们分别传递给invoke_method函数进行调用。由于多态的特性,无论是父类对象还是子类对象,都可以正常调用父类的方法。

    继承和多态是面向对象编程中非常重要的概念和技术,可以大大提高代码的可维护性和可扩展性。

    多态是面向对象的三大特征之一

    多态是面向对象编程中的一个重要特征,它可以使得不同类型的对象对于相同的消息作出不同的响应。在多态的概念中,一个对象可以以多种形态去呈现。

    定义两个类

    首先,我们定义了两个类A和B,并给它们添加了一些方法和属性。这两个类分别表示不同的对象类型。

    class A:
        def __init__(self, name):
            self._name = name
    
        @property
        def name(self):
            return self._name
            
        @name.setter
        def name(self, name):
            self._name = name   
    
    class B:
        def __init__(self, name):
            self._name = name
    
        def __len__(self):
            return 10
    
        @property
        def name(self):
            return self._name
            
        @name.setter
        def name(self, name):
            self._name = name   
    
    class C:
        pass
    
    a = A('孙悟空')
    b = B('猪八戒')
    c = C()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    定义一个函数

    接下来,我们定义了一个函数say_hello(obj),它接受一个参数obj。这个函数并不考虑对象的具体类型,只要对象中含有name属性,就可以作为参数传递给该函数。

    def say_hello(obj):
        print('你好 %s' % obj.name)
    
    • 1
    • 2

    此时,我们可以调用say_hello函数,并传入不同类型的对象作为参数,函数会根据对象的属性打印相应的问候语。

    say_hello(a)  # 输出:你好 孙悟空
    say_hello(b)  # 输出:你好 猪八戒
    
    • 1
    • 2

    鸭子类型

    在面向对象编程中,鸭子类型是一种动态类型的概念。它将对象的适用性基于它们所具有的方法和属性,而不是通过继承关系或实现特定接口来确定。

    我们以len()函数为例,只要一个对象中具有__len__特殊方法,就可以通过len()来获取它的长度。

    l = [1, 2, 3]
    s = 'hello'
    
    print(len(l))  # 输出:3
    print(len(s))  # 输出:5
    print(len(b))  # 输出:10
    print(len(c))  # 报错:AttributeError: 'C' object has no attribute '__len__'
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在上面的代码中,我们可以看到通过len()函数,可以获取列表l和字符串s的长度,但是无法获取类C的长度。这是因为类B定义了__len__方法,而类C没有。

    面向对象编程基础之封装和抽象

    在面向对象编程中,封装和抽象是两个重要的概念,它们帮助我们更好地组织和管理代码。让我们一起来学习一下封装和抽象的用法和特点。

    封装

    封装是面向对象编程中的一种机制,它将数据和操作数据的方法封装在一个单元中,并对外隐藏了具体的实现细节。通过封装,我们可以将数据和方法组织成一个逻辑上的整体,提高代码的可读性和可维护性。

    class Student(object):
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def get_name(self):
            return self.name
    
        def set_name(self, name):
            self.name = name
    
        def get_age(self):
            return self.age
    
        def set_age(self, age):
            self.age = age
    
    student = Student('张三', 18)
    print(student.get_name())  # 输出:张三
    print(student.get_age())   # 输出:18
    
    student.set_name('李四')
    student.set_age(20)
    print(student.get_name())  # 输出:李四
    print(student.get_age())   # 输出:20
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    在上述代码中,我们定义了一个Student类,该类封装了学生的姓名和年龄属性,并提供了获取和设置属性值的方法。通过这种方式,我们可以控制属性的访问权限,以及对属性进行合理的验证和处理。

    抽象

    抽象是面向对象编程中的一个重要原则,它将共同的属性和方法抽象出来,形成一个抽象类或接口。抽象类不能被实例化,只能作为其他类的父类,子类必须实现抽象类中定义的所有抽象方法。

    from abc import ABC, abstractmethod
    
    class Animal(ABC):
        @abstractmethod
        def make_sound(self):
            pass
    
    class Dog(Animal):
        def make_sound(self):
            print('汪汪汪')
    
    class Cat(Animal):
        def make_sound(self):
            print('喵喵喵')
    
    #animal = Animal()  # 错误,抽象类不能被实例化
    
    dog = Dog()
    dog.make_sound()  # 输出:汪汪汪
    
    cat = Cat()
    cat.make_sound()  # 输出:喵喵喵
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    在上述代码中,我们定义了一个抽象类Animal,其中包含了一个抽象方法make_sound()。这个抽象方法没有具体的实现,而是留给子类来实现。然后,我们创建了DogCat两个子类,并分别实现了抽象方法。通过抽象类的使用,我们可以确保子类中一定会实现特定的方法。

    封装和抽象是面向对象编程中非常重要的概念和技术,可以帮助我们构建更可靠和可扩展的代码。

    面向对象编程基础之组合和接口

    在面向对象编程中,除了继承和多态外,还有两个重要的概念:组合和接口。让我们一起来学习一下组合和接口的用法和特点。

    组合

    组合是指将不同的类组合在一起形成一个更大的类。通过组合,我们可以在一个类中引用其他类的对象作为其属性,从而构建出更复杂的对象结构。

    class Engine:
        def start(self):
            print("引擎启动")
    
        def stop(self):
            print("引擎停止")
    
    class Car:
        def __init__(self):
            self.engine = Engine()
    
        def drive(self):
            self.engine.start()
            print("汽车行驶中")
            self.engine.stop()
    
    car = Car()
    car.drive()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    在上述代码中,我们定义了一个Car类和一个Engine类。Car类通过将Engine对象作为属性,实现了对引擎的组合。通过这种方式,我们可以在Car类中调用Engine对象的方法,实现汽车的启动和停止功能。

    接口

    接口是一种约定,它规定了一个类应该具有哪些属性和方法。在面向对象编程中,接口描述了一组相关的操作,但没有具体的实现。通过接口,我们可以定义一套公共的行为标准,从而实现代码的灵活性和可替换性。

    from abc import ABC, abstractmethod
    
    class Shape(ABC):
        @abstractmethod
        def area(self):
            pass
    
        @abstractmethod
        def perimeter(self):
            pass
    
    class Rectangle(Shape):
        def __init__(self, width, height):
            self.width = width
            self.height = height
    
        def area(self):
            return self.width * self.height
    
        def perimeter(self):
            return 2 * (self.width + self.height)
    
    class Circle(Shape):
        def __init__(self, radius):
            self.radius = radius
    
        def area(self):
            return 3.14 * self.radius * self.radius
    
        def perimeter(self):
            return 2 * 3.14 * self.radius
    
    rectangle = Rectangle(5, 3)
    print(rectangle.area())       # 输出:15
    print(rectangle.perimeter())  # 输出:16
    
    circle = Circle(4)
    print(circle.area())          # 输出:50.24
    print(circle.perimeter())     # 输出:25.12
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    在上述代码中,我们定义了一个Shape接口,其中包含了两个抽象方法area()perimeter()。然后,我们创建了两个实现了Shape接口的子类:RectangleCircle。通过接口的使用,我们可以保证所有实现了Shape接口的类都具有相同的方法,从而实现代码的统一处理。

    组合和接口是面向对象编程中非常重要的概念和技术,可以帮助我们构建更灵活和可扩展的代码。

    总结

    面向对象编程(Object-Oriented Programming,简称OOP)是一种用于组织和管理代码的编程范式。它基于对象的概念,将数据和操作封装在一个独立的实体中,通过类之间的交互实现代码的灵活性、可读性和可维护性。

    面向对象编程具备以下几个基本特征:

    封装:将数据和对数据的操作封装在一个实体中,通过访问控制来隐藏内部实现细节,提高代码的安全性和模块化。

    继承:通过继承机制,一个类可以从另一个类派生,继承父类的属性和方法,并在此基础上进行扩展或修改,实现代码的重用和层次化设计。

    多态:同一个方法在不同的对象上调用可以产生不同的行为,通过多态性可以使用统一的接口处理不同类型的对象,提高代码的灵活性和可扩展性。

    抽象:通过抽象类或接口定义规范和约束,隐藏实现细节,强调代码的高层逻辑和整体架构,提高代码的模块化和可维护性。

    在面向对象编程中,我们可以通过定义类来创建对象,并调用对象的方法来实现具体的功能。通过组合多个对象,我们可以构建更加复杂的系统和数据结构。

    此外,面向对象编程还引入了一些设计原则和模式,如单一职责原则、开放封闭原则和设计模式等,帮助我们设计出高内聚低耦合、可扩展和易于维护的代码。

    通过学习面向对象编程的基础知识,我们可以更好地理解和应用这种编程范式,提升自己的软件开发能力。

  • 相关阅读:
    字符串的简单介绍和字符串的大小比较
    Python 简单练习题100道,
    基于leetcode的算法训练:Day1
    ClickHouse多种安装方式
    设计模式-六大设计原则
    Leetcode 724. Find Pivot Index (Python)
    2022年认证杯SPSSPRO杯数学建模B题(第一阶段)唐宋诗的定量分析与比较研究求解全过程文档及程序
    influxdb2.7基本介绍安装与启动
    SpringMVC的常用注解有哪些?
    计算机视觉的应用14-目标检测经典算法之YOLOv1-YOLOv5的模型架构与改进过程详解,便于记忆
  • 原文地址:https://blog.csdn.net/qq_41308872/article/details/132852949