面向对象编程概念

发布于:2025-02-10 ⋅ 阅读:(40) ⋅ 点赞:(0)

1.类

类(Class)

  • 概念:
    类是面向对象编程中的基本构建块,它是对具有相同属性和行为的对象的抽象描述。类定义了对象的属性(成员变量)和操作(成员函数)。
  • 代码示例:
class Person {
private:
    std::string name;
    int age;
public:
    Person(const std::string& n, int a) : name(n), age(a) {}
    void display() {
        std::cout << "Name: " << name << ", Age: " << age << std::endl;
    }
};

int main() {
    Person p("Alice", 25);
    p.display();
    return 0;
}

解释:

  • Person 类包含nameage 成员变量,以及 display 成员函数,用来描述一个人的属性和展示信息的操作。

2.对象

对象(Object)

  • 概念:
    对象是类的实例,是根据类的定义创建的具体实体,拥有类中定义的属性和行为。

  • 代码示例:

class Car {
private:
    std::string brand;
    int year;
public:
    Car(const std::string& b, int y) : brand(b), year(y) {}
    void start() {
        std::cout << "The " << brand << " car from " << year << " is starting." << std::endl;
    }
};

int main() {
    Car myCar("Toyota", 2020); // 创建一个 Car 类的对象 myCar
    myCar.start();
    return 0;
}

解释:

  • myCarCar 类的对象,拥有 brandyear 属性,以及 start 操作。

3.继承

继承(Inheritance)

  • 概念:
    允许一个类(子类或派生类)继承另一个类(父类或基类)的属性和方法,建立 “is-a” 关系。子类可以扩展、修改父类的行为或添加新的属性和方法。
  • 代码示例:
class Animal {
public:
    virtual void makeSound() {
        std::cout << "Animal makes a sound." << std::endl;
    }
};

class Dog : public Animal {
public:
    void makeSound() override {
        std::cout << "Dog barks." << std::endl;
    }
};

int main() {
    Animal* animal = new Dog();
    animal->makeSound(); // 多态性,调用 Dog 的 makeSound 方法
    delete animal;
    return 0;
}

解释:

  • Dog 类继承自 Animal 类,重写了 makeSound 方法,体现了继承和多态。

4.多态

多态(Polymorphism)

  • 概念:
    多态性允许不同的对象对相同的消息做出不同的响应,通常通过虚函数和继承实现,包括编译时多态(函数重载)和运行时多态(虚函数)。
  • 代码示例(运行时多态):
class Shape {
public:
    virtual void draw() = 0;
};

class Circle : public Shape {
public:
    void draw() override {
        std::cout << "Drawing a circle." << std::endl;
    }
};

class Rectangle : public Shape {
public:
    void draw() override {
        std::cout << "Drawing a rectangle." << std::endl;
    }
};

int main() {
    Shape* shape1 = new Circle();
    Shape* shape2 = new Rectangle();
    shape1->draw(); // 调用 Circle 的 draw 方法
    shape2->draw(); // 调用 Rectangle 的 draw 方法
    delete shape1;
    delete shape2;
    return 0;
}

解释:

  • 通过基类指针调用虚函数,根据对象的实际类型调用相应的派生类的 draw 方法,实现运行时多态。

5.组合

组合(Composition)

  • 概念:
    组合是一种对象之间的关系,一个对象包含其他对象作为其成员,建立 “has-a” 关系,将多个对象组合成一个更复杂的对象。
  • 代码示例:
class Engine {
public:
    void start() {
        std::cout << "Engine starts." << std::endl;
    }
};

class Car {
private:
    Engine engine;
public:
    void start() {
        engine.start();
    }
};

int main() {
    Car car;
    car.start();
    return 0;
}

解释:

  • Car 类包含 Engine 类对象,通过组合来实现 Car 的功能。

6.封装

封装(Encapsulation)

  • 概念:
    将数据和操作数据的方法绑定在一起,并使用访问修饰符控制对它们的访问,隐藏内部实现细节。
  • 代码示例:
class BankAccount {
private:
    double balance;
public:
    BankAccount() : balance(0.0) {}
    void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
        }
    }
    double getBalance() const {
        return balance;
    }
};

int main() {
    BankAccount account;
    account.deposit(100.0);
    std::cout << "Balance: " << account.getBalance() << std::endl;
    return 0;
}

解释:

  • balance 成员变量被封装在 BankAccount 类中,外部只能通过 depositgetBalance
    方法访问,保护了数据的安全性。

7.抽象

抽象(Abstraction)

  • 概念:
    抽象是对复杂事物的简化,通过抽象类和接口定义对象的基本特征和行为,而不涉及具体实现。抽象类包含抽象方法,接口是纯抽象类。
  • 代码示例:
class Vehicle {
public:
    virtual void move() = 0;
    virtual ~Vehicle() = default;
};

class Car : public Vehicle {
public:
    void move() override {
        std::cout << "Car is moving." << std::endl;
    }
};

int main() {
    Vehicle* vehicle = new Car();
    vehicle->move();
    delete vehicle;
    return 0;
}

解释:

  • Vehicle 是抽象类,定义了 move 抽象方法,Car 类实现了 move 方法,抽象类为派生类提供了规范。

8.接口

接口(Interface)

  • 概念:
    接口定义了一组方法,类通过实现这些方法来提供具体功能,通常使用纯虚函数的抽象类表示。
  • 代码示例:
class Printable {
public:
    virtual void print() = 0;
    virtual ~Printable() = default;
};

class Document : public Printable {
public:
    void print() override {
        std::cout << "Printing document." << std::endl;
    }
};

int main() {
    Printable* doc = new Document();
    doc->print();
    delete doc;
    return 0;
}

解释:

  • Printable 是接口,Document 类实现了 print 方法,遵循接口定义的规范。

9.重载

重载(Overloading)

  • 概念:
    函数重载是指在同一作用域内,多个函数可以具有相同的名称但不同的参数列表,运算符重载是为已有运算符赋予新的操作含义。
  • 代码示例(函数重载):
class Math {
public:
    int add(int a, int b) {
        return a + b;
    }
    double add(double a, double b) {
        return a + b;
    }
};

int main() {
    Math m;
    std::cout << m.add(1, 2) << std::endl;       // 调用 int add(int, int)
    std::cout << m.add(1.5, 2.5) << std::endl; // 调用 double add(double, double)
    return 0;
}

解释:

  • 不同参数类型的 add 函数,根据输入参数调用相应的函数。

10.重写

重写(Overriding)

  • 概念:
    在派生类中重新定义基类的虚函数,实现派生类特有的行为。
  • 代码示例:
class Base {
public:
    virtual void show() {
        std::cout << "Base::show()" << std::endl;
    }
};

class Derived : public Base {
public:
    void show() override {
        std::cout << "Derived::show()" << std::endl;
    }
};

int main() {
    Base* basePtr = new Derived();
    basePtr->show(); // 调用 Derived 的 show 方法
    delete basePtr;
    return 0;
}

解释:

  • Derived 类重写了 Base 类的 show 方法,体现多态性。

11.协变返回类型

协变返回类型(Covariant Return Types)

  • 概念:
    在重写虚函数时,允许派生类的重写函数返回的指针或引用的类型是基类中相应虚函数返回类型的派生类型。
  • 代码示例:
class Base {
public:
    virtual Base* clone() = 0;
    virtual ~Base() = default;
};

class Derived : public Base {
public:
    Derived* clone() override {
        return new Derived();
    }
};

int main() {
    Base* basePtr = new Derived();
    Derived* derivedPtr = dynamic_cast<Derived*>(basePtr->clone());
    delete basePtr;
    delete derivedPtr;
    return 0;
}

解释:

  • Derived 类重写 clone 函数,返回类型为 Derived*,是基类 Base* 的派生类型。

12.虚析构函数

虚析构函数(Virtual Destructor)

  • 概念:
    基类的析构函数设为虚函数,确保通过基类指针删除派生类对象时正确调用派生类析构函数,防止内存泄漏。
  • 代码示例:
class Base {
public:
    virtual ~Base() {
        std::cout << "Base destructor." << std::endl;
    }
};

class Derived : public Base {
public:
    ~Derived() override {
        std::cout << "Derived destructor." << std::endl;
    }
};

int main() {
    Base* basePtr = new Derived();
    delete basePtr; // 先调用 Derived 的析构函数,再调用 Base 的析构函数
    return 0;
}

解释:

  • 虚析构函数保证了正确的析构顺序。

13.静态成员

静态成员(Static Members)

  • 概念:
    静态成员属于类而不是对象,所有对象共享静态成员变量,静态成员函数可以在不创建对象的情况下调用。
  • 代码示例:
class Counter {
public:
    static int count;
    static void increment() {
        count++;
    }
};

int Counter::count = 0;

int main() {
    Counter::increment();
    Counter::increment();
    std::cout << Counter::count << std::endl; // 输出 2
    return 0;
}

解释:

  • count 是静态成员变量,increment是静态成员函数,通过类名直接调用。

14.友元

友元(Friend)

  • 概念:
    允许一个函数或类访问另一个类的私有或保护成员,破坏封装性,应谨慎使用。
  • 代码示例:
class A {
private:
    int data;
    friend void displayData(const A& a);
public:
    A(int d) : data(d) {}
};

void displayData(const A& a) {
    std::cout << "Data: " << a.data << std::endl;
}

int main() {
    A obj(10);
    displayData(obj);
    return 0;
}

解释:

  • displayData 函数是 A 类的友元函数,可以访问 A 类的私有成员 data

15.构造函数

构造函数(Constructor)

  • 概念:
    构造函数是类的特殊成员函数,用于初始化对象的成员变量,在对象创建时自动调用。
  • 代码示例:
class Point {
private:
    int x, y;
public:
    Point(int xVal, int yVal) : x(xVal), y(yVal) {}
    void display() {
        std::cout << "Point: (" << x << ", " << y << ")" << std::endl;
    }
};

int main() {
    Point p(3, 4);
    p.display();
    return 0;
}

解释:

  • Point(int xVal, int yVal) 是构造函数,初始化 xy 成员变量。

16.析构函数

析构函数(Destructor)

  • 概念:
    析构函数是在对象销毁时自动调用的特殊成员函数,用于释放资源。
  • 代码示例:
class Resource {
public:
    Resource() {
        std::cout << "Resource acquired." << std::endl;
    }
    ~Resource() {
        std::cout << "Resource released." << std::endl;
    }
};

int main() {
    Resource r; // 创建对象时调用构造函数,销毁时调用析构函数
    return 0;
}

解释:

  • ~Resource() 是析构函数,在对象 r 销毁时释放资源。

17.拷贝析构函数

拷贝构造函数(Copy Constructor)

  • 概念:
    用于通过一个已有对象创建新对象,进行对象的复制,默认拷贝构造函数进行浅拷贝,可能需要自定义深拷贝。
  • 代码示例:
class Array {
private:
    int* data;
    int size;
public:
    Array(int s) : size(s) {
        data = new int[size];
        for (int i = 0; i < size; ++i) {
            data[i] = i;
        }
    }
    Array(const Array& other) : size(other.size) {
        data = new int[size];
        for (int i = 0; i < size; ++i) {
            data[i] = other.data[i];
        }
    }
    ~Array() {
        delete[] data;
    }
    void display() {
        for (int i = 0; i < size; ++i) {
            std::cout << data[i] << " ";
        }
        std::cout << std::endl;
    }
};

int main() {
    Array a(5);
    Array b = a; // 调用拷贝构造函数
    a.display();
    b.display();
    return 0;
}

解释:

  • Array(const Array& other) 是拷贝构造函数,实现深拷贝,避免浅拷贝导致的指针共享问题。

18移动析构函数

移动构造函数(Move Constructor)

  • 概念:
    用于将资源从一个对象转移到另一个对象,提高性能,避免不必要的复制。
  • 代码示例:
#include <iostream>
#include <utility>

class Array {
private:
    int* data;
    int size;
public:
    Array(int s) : size(s) {
        data = new int[size];
        for (int i = 0; i < size; ++i) {
            data[i] = i;
        }
    }
    Array(const Array& other) : size(other.size) {
        data = new int[size];
        for (int i = 0; i < size; ++i) {
            data[i] = other.data[i];
        }
    }
    Array(Array&& other) : size(other.size), data(other.data) {
        other.data = nullptr;
    }
    ~Array() {
        delete[] data;
    }
    void display() {
        for (int i = 0; i < size; ++i) {
            std::cout << data[i] << " ";
        }
        std::cout << std::endl;
    }
};

int main() {
    Array a(5);
    Array b = std::move(a); // 调用移动构造函数
    a.display(); // 可能输出不确定结果,因为 a 的数据已被移动
    b.display();
    return 0;
}

解释:

  • Array(Array&& other) 是移动构造函数,将 other 对象的数据移动到新对象,避免复制操作。