面向对象编程:C++中的类和对象

面向对象编程是一种程序设计范式,它将真实世界的概念抽象为对象,并通过对象之间的交互来实现程序功能。C++是一种支持面向对象编程的编程语言,其中类和对象是面向对象编程的核心概念。

一、类和对象的概念

类是一种抽象数据类型,它描述了一组具有相同特征和行为的对象。类定义了对象的属性和方法。对象是类的一个实例,它具有类定义的所有属性和方法。例如,人类可以被描述为一个类,而每个人则是这个类的一个对象。

C++中定义类的语法如下:

class className {
public:
    // 属性和方法
}

其中,className是类的名称,public表示该类的属性和方法可以被其他类访问。

定义类的属性和方法类似于定义变量和函数:

class Person {
public:
    string name;
    int age;
    void sayHello() {
        cout << "Hello, my name is " << name << ", I'm " << age << " years old." << endl;
    }
};

上面的代码定义了一个Person类,其中包含了name和age两个属性,以及一个sayHello()方法。这个方法用于输出“Hello, my name is xxx, I'm xxx years old.”。

声明一个对象的语法为:

className objectName;

其中,className是类名称,objectName是对象名称。例如,我们可以声明一个Person对象:

Person p1;

这个对象p1将具有Person类定义的所有属性和方法。

二、类的访问修饰符

C++中,类的访问修饰符用于控制类的属性和方法的访问级别。C++中有三种访问修饰符,分别是public、private和protected。它们的区别如下:

  • public属性和方法可以被任何类访问。
  • private属性和方法只能被本类中的方法访问,不能被其他类访问。
  • protected属性和方法可以在本类和子类中访问,但不能在其他类中直接访问。

下面是示例代码,演示使用不同的访问修饰符:

class Person {
    public:
        string name;        // public属性
        void sayHello() {   // public方法
            cout << "Hello, my name is " << name << endl;
        }
    private:
        int age;            // private属性
        void setAge(int a) {// private方法
            age = a;
        }
    protected:
        string address;     // protected属性
};

class Student : public Person {
public:
    void setAddress(string a) {
        address = a;        // 可以访问父类的protected属性
    }
};

int main() {
    Person p1;
    p1.name = "Jane";
    p1.sayHello();
    // p1.age = 20;        // 错误:不能访问private属性
    // p1.setAge(20);      // 错误:不能访问private方法

    Student s1;
    s1.setAddress("Beijing");
    // s1.age = 20;        // 错误:不能访问父类的private属性
    // s1.setAge(20);      // 错误:不能访问父类的private方法

    return 0;
}

上面的代码演示了Person类和Student类的定义,以及访问修饰符的使用。在Main函数中,我们可以看到,公共属性和方法可以在任何地方访问,私有属性和方法只能在本类中访问,而受保护属性和方法可以在本类和子类中访问。

三、构造函数和析构函数

构造函数和析构函数是面向对象编程中的重要概念,它们分别用于创建和销毁对象。

构造函数是一个特殊的方法,用于在创建对象时初始化对象的属性。C++中的构造函数名称与类名相同,在定义过程中没有返回值类型,例如:

class Person {
public:
    Person(string n, int a) {  // 构造函数
        name = n;
        age = a;
    }
    void sayHello() {
        cout << "Hello, my name is " << name << ", I'm " << age << " years old." << endl;
    }
private:
    string name;
    int age;
};

上面的代码定义了一个Person类,其中有一个构造函数,用于在创建Person对象时初始化对象的属性。构造函数的参数是待初始化的属性值。

类似的,析构函数也是一个特殊的方法,用于在销毁对象时释放对象的资源。C++中的析构函数名称与类名相同,但在名称前面加上一个波浪线(~),例如:

class Person {
public:
    Person(string n, int a) {
        name = n;
        age = a;
    }
    ~Person() {     // 析构函数
        cout << "Person object is destroyed." << endl;
    }
    void sayHello() {
        cout << "Hello, my name is " << name << ", I'm " << age << " years old." << endl;
    }
private:
    string name;
    int age;
};

在上面的代码中,析构函数用于在销毁Person对象时输出一条消息。

四、static成员变量和方法

类的static成员变量和方法是属于整个类而不是某个对象的。static成员变量和方法可以在对象创建之前就存在,因此它们可以在没有对象的情况下直接访问。例如:

class Person {
public:
    static int count;  // 定义一个静态成员变量
    Person(string n, int a) {
        name = n;
        age = a;
        count++;        // 静态成员变量count加1
    }
    ~Person() {
        count--;        // 静态成员变量count减1
    }
    static void getCount() {    // 定义一个静态成员方法
        cout << "count = " << count << endl;
    }
private:
    string name;
    int age;
};

int Person::count = 0;  // 静态成员变量需要在类外进行初始化

int main() {
    Person p1("John", 20);
    Person::getCount(); // 静态方法可以通过类名来调用
    Person p2("Jane", 22);
    Person::getCount();
    Person p3("Mary", 25);
    Person::getCount();
    return 0;
}

上面的代码演示了如何定义和使用静态成员变量和方法。在Person类定义中,我们定义了一个静态成员变量count和一个静态方法getCount()。在Main函数中,我们创建了三个Person对象,每次创建对象都会使count加1。通过调用静态方法getCount(),我们可以输出count的值。

五、继承

继承是面向对象编程中的一个重要概念,它可以让一个类继承另一个类的属性和方法,从而避免代码重复。在C++中使用":"符号表示继承关系,例如:

class Student : public Person {    // Student类继承自Person类
public:
    string school;
    void study() {
        cout << name << " is studying in " << school << endl;
    }
};

int main() {
    Student s1;
    s1.name = "John";
    s1.age = 20;
    s1.school = "MIT";
    s1.sayHello();
    s1.study();
    return 0;
}

在上面的代码中,我们创建了一个Student类,并让它继承自Person类。由于继承了Person类,Student类可以使用Person类中的属性和方法。在Main函数中,我们创建一个Student对象s1,并为它设置属性值。通过调用sayHello()和study()方法,我们可以输出一些信息。

六、多态

多态是C++中面向对象编程的重要概念,它指的是同一种行为具有多种不同的表现形式。多态性是面向对象程序设计的一个重要的特点,它可以提高程序的灵活性和可维护性。

C++中多态的实现方式有两种,分别是函数重载和虚函数。

函数重载是指在同一个类中,可以定义多个名称相同但参数类型和个数不同的函数。例如:

class Calculator {
public:
    int add(int a, int b) {
        cout << "Addition of two integers: ";
        return a + b;
    }
    float add(float a, float b) {
        cout << "Addition of two floats: ";
        return a + b;
    }
};

int main() {
    Calculator c1;
    cout << c1.add(3, 5) << endl;       // 输出8
    cout << c1.add(3.1f, 5.7f) << endl; // 输出8.8
    return 0;
}

在上面的代码中,我们定义了一个Calculator类,并在其中定义了两个名称相同但参数类型和个数不同的add()方法。在Main函数中,我们分别调用两个add()方法,并输出计算结果。由于参数类型和个数不同,因此C++可以识别出应该调用哪个add()方法。

虚函数是指在基类中定义一个虚函数,在派生类中可以对该虚函数进行重定义。虚函数的定义方式为,在函数前加上关键字virtual,例如:

class Shape {
public:
    virtual float area() { return 0; }
    virtual float perimeter() { return 0; }
};

class Rectangle : public Shape {
public:
    Rectangle(float l, float w) {
        length = l;
        width = w;
    }
    float area() { return length * width; }
    float perimeter() { return 2 * (length + width); }
private:
    float length;
    float width;
};

class Circle : public Shape {
public:
    Circle(float r) {
        radius = r;
    }
    float area() { return PI * radius * radius; }
    float perimeter() { return 2 * PI * radius; }
private:
    float radius;
    const float PI = 3.1415926;
};

int main() {
    Shape* s1;
    Rectangle r1(3, 4);
    Circle c1(2);
    s1 = &r1;
    cout << "Rectangle area: " << s1->area() << endl;
    cout << "Rectangle perimeter: " << s1->perimeter() << endl;
    s1 = &c1;
    cout << "Circle area: " << s1->area() << endl;
    cout << "Circle perimeter: " << s1->perimeter() << endl;
    return 0;
}

在上面的代码中,我们定义了一个Shape类,并在其中定义了一个虚函数area()和perimeter()。在Rectangle和Circle类中,我们分别对这两个方法进行了重定义。在Main函数中,我们声明了一个Shape指针s1,指向一个Rectangle对象r1。然后我们调用了s1的area()和perimeter()方法,由于Shape类中的area()和perimeter()方法是虚函数,在运行时会根据对象的类型调用相应的方法,因此输出的结果分别是Rectangle类和Circle类中的方法返回值。这就是多态性的体现。

本文链接:https://my.lmcjl.com/post/16358.html

展开阅读全文

4 评论

留下您的评论.