第十二课 面向对象

面向对象是软件工程的常用方法,它利于项目维护、分工协作等等。面向对象通过类、对象等高级抽象来描述现实世界的问题。

面向对象三大特性:封装、继承、多态

一、封装

  • 把数据和操作封装进类
  • 隐藏内部细节,对外提供接口
  • 保护数据安全

类的定义

#include <iostream>
#include <string>
using namespace std;

// 定义类
class Student {
private:  // 私有成员:类外部不能直接访问
    string name;
    int age;
    double score;

public:  // 公有成员:外部可以直接访问
    // 成员函数(方法)
    void setInfo(string n, int a, double s) {
        name = n;
        age = a;
        score = s;
    }

    void show() {
        cout << "姓名:" << name << endl;
        cout << "年龄:" << age << endl;
        cout << "成绩:" << score << endl;
    }

    // 获取私有成员的值(getter)
    string getName() {
        return name;
    }

    int getAge() {
        return age;
    }
};

int main() {
    // 创建对象
    Student s1;

    // 通过公有方法访问私有成员
    s1.setInfo("Tom", 18, 90.5);
    s1.show();

    // s1.name = "Tom";  // 错误:name是私有成员,不能直接访问

    cout << s1.getName() << endl;  // Tom

    return 0;
}

构造函数和析构函数

#include <iostream>
#include <string>
using namespace std;

class Student {
private:
    string name;
    int age;

public:
    // 构造函数:对象创建时自动调用
    Student() {
        cout << "构造函数调用" << endl;
        name = "未知";
        age = 0;
    }

    // 有参构造函数
    Student(string n, int a) {
        cout << "有参构造函数调用" << endl;
        name = n;
        age = a;
    }

    // 析构函数:对象销毁时自动调用
    ~Student() {
        cout << "析构函数调用:" << name << endl;
    }

    void show() {
        cout << name << " " << age << endl;
    }
};

int main() {
    Student s1;              // 调用无参构造函数
    Student s2("Tom", 18);   // 调用有参构造函数

    s1.show();
    s2.show();

    return 0;
    // 程序结束前会调用析构函数
}

二、继承

  • 子类继承父类的特性
  • 代码复用
  • 建立类与类之间的关系

继承示例

#include <iostream>
#include <string>
using namespace std;

// 父类(基类)
class Person {
public:
    string name;
    int age;

    void show() {
        cout << "姓名:" << name << ",年龄:" << age << endl;
    }
};

// 子类(派生类)
class Student : public Person {
public:
    int score;  // 新增成员

    void showScore() {
        cout << name << "的成绩:" << score << endl;
    }
};

int main() {
    Student s;
    s.name = "Tom";   // 继承自父类的成员
    s.age = 18;       // 继承自父类的成员
    s.score = 90;     // 子类自己的成员

    s.show();         // 调用继承的方法
    s.showScore();    // 调用子类的方法

    return 0;
}

继承的构造函数和析构函数

#include <iostream>
using namespace cout = std::cout;
using namespace std;

class Person {
public:
    Person() {
        cout << "Person构造函数" << endl;
    }
    ~Person() {
        cout << "Person析构函数" << endl;
    }
};

class Student : public Person {
public:
    Student() {
        cout << "Student构造函数" << endl;
    }
    ~Student() {
        cout << "Student析构函数" << endl;
    }
};

int main() {
    Student s;
    // 输出:
    // Person构造函数
    // Student构造函数

    return 0;
    // 输出:
    // Student析构函数
    // Person析构函数
}

三、多态

  • 同一接口,不同实现
  • 父类指针指向子类对象
  • 使用virtual实现

多态示例

#include <iostream>
#include <string>
using namespace std;

// 父类
class Animal {
public:
    // 虚函数:允许子类重写
    virtual void speak() {
        cout << "动物叫声" << endl;
    }
};

// 子类
class Dog : public Animal {
public:
    // 重写父类的虚函数
    void speak() override {
        cout << "汪汪汪" << endl;
    }
};

class Cat : public Animal {
public:
    void speak() override {
        cout << "喵喵喵" << endl;
    }
};

int main() {
    Animal *p1 = new Dog();   // 父类指针指向子类对象
    Animal *p2 = new Cat();

    p1->speak();  // 输出:汪汪汪(多态)
    p2->speak();  // 输出:喵喵喵(多态)

    delete p1;
    delete p2;

    return 0;
}

纯虚函数和抽象类

#include <iostream>
using namespace std;

// 抽象类:包含纯虚函数的类
class Shape {
public:
    // 纯虚函数:没有实现,必须由子类重写
    virtual double area() const = 0;
};

// 圆形
class Circle : public Shape {
private:
    double radius;
public:
    Circle(double r) : radius(r) {}

    double area() const override {
        return 3.14159 * radius * radius;
    }
};

// 矩形
class Rectangle : public Shape {
private:
    double width, height;
public:
    Rectangle(double w, double h) : width(w), height(h) {}

    double area() const override {
        return width * height;
    }
};

int main() {
    Shape *shapes[2];
    shapes[0] = new Circle(5);
    shapes[1] = new Rectangle(4, 6);

    cout << "圆形面积:" << shapes[0]->area() << endl;  // 78.53975
    cout << "矩形面积:" << shapes[1]->area() << endl;   // 24

    return 0;
}

访问控制

#include <iostream>
using namespace std;

class MyClass {
public:     // 公有:类内外都能访问
    int a;

protected:  // 保护:类内和子类能访问
    int b;

private:    // 私有:只有类内能访问
    int c;
};

class SubClass : public MyClass {
public:
    void test() {
        a = 1;   // 公有:可以访问
        b = 2;   // 保护:子类可以访问
        // c = 3; // 私有:不能访问
    }
};

int main() {
    MyClass obj;
    obj.a = 1;   // 公有:可以访问
    // obj.b = 2; // 保护:不能访问
    // obj.c = 3; // 私有:不能访问

    return 0;
}

友元函数

#include <iostream>
using namespace std;

class MyClass {
private:
    int data;

public:
    MyClass(int d) : data(d) {}

    // 声明友元函数:可以访问私有成员
    friend void showData(MyClass &obj);
};

// 友元函数实现
void showData(MyClass &obj) {
    cout << "私有数据:" << obj.data << endl;
}

int main() {
    MyClass obj(100);
    showData(obj);  // 输出:私有数据:100

    return 0;
}

静态成员

#include <iostream>
using namespace std;

class MyClass {
public:
    int normalVar;       // 普通成员:每个对象一份
    static int staticVar; // 静态成员:所有对象共享

    MyClass(int n) : normalVar(n) {
        staticVar++;  // 对象创建时,静态成员+1
    }

    static void showCount() {
        // 静态函数只能访问静态成员
        cout << "对象数量:" << staticVar << endl;
    }
};

// 静态成员需要在类外初始化
int MyClass::staticVar = 0;

int main() {
    MyClass::showCount();  // 0

    MyClass obj1(10);
    MyClass::showCount();  // 1

    MyClass obj2(20);
    MyClass::showCount();  // 2

    return 0;
}

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注