关联关系理解

关联关系理解这样 订单对象可以通过指针访问关联的客户对象的信息 但客户对象无法直接通过订单对象访问关联的订单信息 从而形成了单向关联关系

大家好,欢迎来到IT知识分享网。


1.关联关系

关联关系的特点包括:

  1. 双向关系:两个类之间的关联可以是双向的,即彼此互相关联。
  2. 多重性:关联关系中的对象之间可能存在一对一、一对多、多对一或多对多等不同的关系。
  3. 独立性:关联关系中的两个对象的生命周期通常是独立的,它们之间的存在并不依赖于彼此。

关联关系在代码实现中通常通过成员变量、方法参数或返回值来体现,以反映出两个类之间的关联性。在使用关联关系时,需要注意避免过度耦合,以提高代码的灵活性和可维护性。

1.1单向关联

在下面的示例中,Order 类中使用了指针 const Customer* customer 来表示订单和客户之间的单向关联关系。在 main 函数中创建订单对象时,将客户对象的地址传入订单对象的构造函数中,从而建立了单向关联关系。这样,订单对象可以通过指针访问关联的客户对象的信息,但客户对象无法直接通过订单对象访问关联的订单信息,从而形成了单向关联关系。

#include <iostream> #include <vector> #include <string> using namespace std; // 定义客户类 class Customer { 
     private: int customerId; string customerName; public: Customer(int id, const string& name) : customerId(id), customerName(name) { 
    } int getCustomerId() const { 
     return customerId; } const string& getCustomerName() const { 
     return customerName; } }; // 定义订单类 class Order { 
     private: int orderId; string orderDate; const Customer* customer; // 使用指针表示关联关系 public: Order(int id, const string& date, const Customer* cust) : orderId(id), orderDate(date), customer(cust) { 
    } int getOrderId() const { 
     return orderId; } const string& getOrderDate() const { 
     return orderDate; } const Customer* getCustomer() const { 
     return customer; } }; int main() { 
     // 创建客户对象 Customer customer1(1, "John Doe"); // 创建订单对象,并传入客户对象的地址作为关联 Order order1(1001, "2024-03-30", &customer1); // 获取订单信息以及关联的客户信息 cout << "Order ID: " << order1.getOrderId() << endl; cout << "Order Date: " << order1.getOrderDate() << endl; cout << "Customer ID: " << order1.getCustomer()->getCustomerId() << endl; cout << "Customer Name: " << order1.getCustomer()->getCustomerName() << endl; return 0; } 

1.2双向关联

双向关联关系意味着两个类之间的关联是双向的,每个类都能够直接访问关联的对象。在 C++ 中实现双向关联关系时,可以在每个类中使用指针或引用来表示另一个类的关联。在下面的示例中,Customer 类和 Order 类分别存储了彼此的指针,并提供了方法来访问关联的对象。在创建订单对象时,将订单添加到客户的订单列表中,从而建立了双向关联关系。

#include <iostream> #include <vector> #include <string> using namespace std; // 前置声明,避免互相引用时出错 class Order; // 定义客户类 class Customer { 
     private: int customerId; string customerName; vector<Order*> orders; // 用于存储关联的订单指针 public: Customer(int id, const string& name) : customerId(id), customerName(name) { 
    } int getCustomerId() const { 
     return customerId; } const string& getCustomerName() const { 
     return customerName; } // 添加订单到客户的订单列表中 void addOrder(Order* order) { 
     orders.push_back(order); } // 获取客户的所有订单 const vector<Order*>& getOrders() const { 
     return orders; } }; // 定义订单类 class Order { 
     private: int orderId; string orderDate; Customer* customer; // 用于存储关联的客户指针 public: Order(int id, const string& date, Customer* cust) : orderId(id), orderDate(date), customer(cust) { 
     // 在订单构造函数中,将订单添加到客户的订单列表中 customer->addOrder(this); } int getOrderId() const { 
     return orderId; } const string& getOrderDate() const { 
     return orderDate; } // 获取订单关联的客户 Customer* getCustomer() const { 
     return customer; } }; int main() { 
     // 创建客户对象和订单对象 Customer customer1(1, "John Doe"); Order order1(1001, "2024-03-30", &customer1); // 获取订单关联的客户以及客户关联的订单 cout << "Order ID: " << order1.getOrderId() << endl; cout << "Order Date: " << order1.getOrderDate() << endl; cout << "Customer ID: " << order1.getCustomer()->getCustomerId() << endl; cout << "Customer Name: " << order1.getCustomer()->getCustomerName() << endl; cout << "Customer's Orders:" << endl; const vector<Order*>& customer1Orders = customer1.getOrders(); for (const auto& order : customer1Orders) { 
     cout << " - Order ID: " << order->getOrderId() << ", Order Date: " << order->getOrderDate() << endl; } return 0; } 

1.3自关联

自关联是指一个类与自身建立关联关系。在 C++ 中,可以通过在类中使用指针或引用来实现自关联。在下面的示例中,Node 类表示一个简单的链表节点,包含一个整数数据成员和一个指向下一个节点的指针。通过在节点类中使用指针来指向下一个节点,实现了节点之间的自关联关系。在 main 函数中,创建了三个节点对象,并通过调用 setNext 方法建立了节点之间的关联关系。然后,通过遍历链表输出节点数据,最后释放了动态分配的内存。

#include <iostream> #include <string> using namespace std; // 定义节点类 class Node { 
     private: int data; Node* next; // 指向下一个节点的指针 public: Node(int val) : data(val), next(nullptr) { 
    } // 设置下一个节点 void setNext(Node* node) { 
     next = node; } // 获取下一个节点 Node* getNext() const { 
     return next; } // 获取节点数据 int getData() const { 
     return data; } }; int main() { 
     // 创建节点对象 Node* node1 = new Node(1); Node* node2 = new Node(2); Node* node3 = new Node(3); // 建立节点之间的关联关系 node1->setNext(node2); node2->setNext(node3); // 遍历节点链表 Node* current = node1; while (current != nullptr) { 
     cout << "Node data: " << current->getData() << endl; current = current->getNext(); } // 释放动态分配的内存 delete node1; delete node2; delete node3; return 0; } 

2.聚合关系

聚合关系是关联关系的一种,是强关联关系,是整体和部分之间的关系。在聚合关系中,一个类作为另一个类的成员,并且这个成员对象的生命周期可以独立于包含它的类。在 C++ 中,聚合关系通常通过在类中创建成员对象或指针来实现。聚合关系的特点是,成员可以脱离于整体对象独立存在,比如学校与老师的关系,学校包含老师,但是就算学校没了,老师依然可以存在。
在下面的示例中,Teacher 类表示老师,School 类表示学校。在 School 类中,使用了一个 vector 来存储学校包含的老师对象的指针,这体现了学校和老师之间的聚合关系。通过 addTeacher 方法可以向学校对象中添加老师。通过 getTeacherNames 方法可以获取学校所有老师的姓名。

#include <iostream> #include <string> #include <vector> using namespace std; // 老师类 class Teacher { 
     private: string name; public: Teacher(const string& n) : name(n) { 
    } const string& getName() const { 
     return name; } }; // 学校类 class School { 
     private: string name; vector<Teacher*> teachers; // 聚合关系,学校包含了多个老师对象的指针 public: School(const string& n) : name(n) { 
    } // 添加老师 void addTeacher(Teacher* teacher) { 
     teachers.push_back(teacher); } // 获取学校所有老师的姓名 vector<string> getTeacherNames() const { 
     vector<string> teacherNames; for (const auto& teacher : teachers) { 
     teacherNames.push_back(teacher->getName()); } return teacherNames; } // 获取学校名称 const string& getName() const { 
     return name; } }; int main() { 
     // 创建老师对象 Teacher mrSmith("Mr. Smith"); Teacher msJohnson("Ms. Johnson"); // 创建学校对象 School highSchool("High School"); // 将老师添加到学校中 highSchool.addTeacher(&mrSmith); highSchool.addTeacher(&msJohnson); // 输出学校名称 cout << "School name: " << highSchool.getName() << endl; // 输出学校所有老师的姓名 cout << "Teachers in " << highSchool.getName() << ":" << endl; for (const auto& teacherName : highSchool.getTeacherNames()) { 
     cout << teacherName << endl; } return 0; } 

3.组合关系

组合表示类之间的整体与部分的关系,但它是一种更强烈的聚合关系。在组合关系中,整体对象可以控制部分对象的生命周期,一旦整体对象不存在,部分对象也将不存在,部分对象不能脱离整体对象而存在在组合关系中,一个类包含另一个类的对象,并且包含的对象的生命周期与包含它的类的生命周期相同。在 C++ 中,组合关系通常通过在类中直接创建成员对象来实现。
在下面的示例中,Wheel 类表示轮子,Car 类表示汽车。Car 类包含了四个 Wheel 类的对象作为成员变量,这实现了 Car 类对 Wheel 类的组合关系。在 main 函数中,创建了一个汽车对象 myCar,并输出了汽车的型号以及每个轮子的尺寸。

#include <iostream> #include <string> using namespace std; // 定义轮子类 class Wheel { 
     private: int size; public: Wheel(int s) : size(s) { 
    } int getSize() const { 
     return size; } }; // 定义汽车类,其中包含轮子对象 class Car { 
     private: string model; Wheel frontLeftWheel; Wheel frontRightWheel; Wheel rearLeftWheel; Wheel rearRightWheel; public: Car(const string& m, int wheelSize) : model(m), frontLeftWheel(wheelSize), frontRightWheel(wheelSize), rearLeftWheel(wheelSize), rearRightWheel(wheelSize) { 
    } const string& getModel() const { 
     return model; } const Wheel& getFrontLeftWheel() const { 
     return frontLeftWheel; } const Wheel& getFrontRightWheel() const { 
     return frontRightWheel; } const Wheel& getRearLeftWheel() const { 
     return rearLeftWheel; } const Wheel& getRearRightWheel() const { 
     return rearRightWheel; } }; int main() { 
     // 创建汽车对象 Car myCar("Toyota", 18); // 输出汽车信息及轮子信息 cout << "Car Model: " << myCar.getModel() << endl; cout << "Front Left Wheel Size: " << myCar.getFrontLeftWheel().getSize() << " inches" << endl; cout << "Front Right Wheel Size: " << myCar.getFrontRightWheel().getSize() << " inches" << endl; cout << "Rear Left Wheel Size: " << myCar.getRearLeftWheel().getSize() << " inches" << endl; cout << "Rear Right Wheel Size: " << myCar.getRearRightWheel().getSize() << " inches" << endl; return 0; } 

4.依赖关系

依赖关系是一种使用关系,它是对象之间耦合度最弱的一种关联方式,是临时性的关联。在代码中,某个类的方法通过局部变量、方法的参数或者对静态方法的调用来访问另一个类(被依赖类)中的某些方法来完成一些职责。在依赖关系中,一个类使用另一个类的对象作为参数或者局部变量,但是它们之间没有拥有关系。依赖关系通常体现在方法参数的传递或局部变量的使用上。
在下面的示例中,Engine 类表示引擎,Car 类表示汽车。在 Car 类的 drive 方法中,使用了 Engine 类的对象作为参数,这体现了 Car 类对 Engine 类的依赖关系。在 main 函数中,创建了一个汽车对象 myCar 和一个引擎对象 myEngine,然后调用了汽车对象的 drive 方法,并将引擎对象作为参数传入。

#include <iostream> #include <string> using namespace std; // 定义引擎类 class Engine { 
     public: void start() { 
     cout << "Engine started." << endl; } void stop() { 
     cout << "Engine stopped." << endl; } }; // 定义汽车类,其中使用了引擎对象作为参数 class Car { 
     private: string model; public: Car(const string& m) : model(m) { 
    } // 方法中使用了引擎对象作为参数,体现了依赖关系 void drive(Engine& engine) { 
     cout << "Driving the " << model << " car." << endl; engine.start(); // Driving logic... engine.stop(); } }; int main() { 
     // 创建汽车对象和引擎对象 Car myCar("Toyota"); Engine myEngine; // 调用汽车对象的方法,传入引擎对象作为参数 myCar.drive(myEngine); return 0; } 

5.继承关系

继承关系是耦合度最大的一种,也是我们最常看见的一种,子类基础父类。在关联关系中,一个类和另一个类有联系,但它们之间的关系不如组合关系密切。通常,一个类的对象可以作为另一个类的成员变量,但它们之间的生命周期可以是独立的。继承关系则是一种类与类之间的特殊关系,其中一个类(子类)可以继承另一个类(父类)的属性和方法。
在下面的示例中,Wheel 类表示轮子,Car 类表示汽车,SportsCar 类表示跑车。Car 类中包含了四个 Wheel 对象的指针,这体现了关联关系。而 SportsCar 类继承自 Car 类,这体现了继承关系。在 main 函数中,创建了一个跑车对象 mySportsCar,并输出了跑车的型号、是否有涡轮增压以及每个轮子的尺寸。

#include <iostream> #include <string> using namespace std; // 定义轮子类 class Wheel { 
     private: int size; public: Wheel(int s) : size(s) { 
    } int getSize() const { 
     return size; } }; // 定义汽车类,其中关联了轮子对象 class Car { 
     private: string model; Wheel* wheels[4]; // 关联了四个轮子对象的指针 public: Car(const string& m, int wheelSize) : model(m) { 
     for (int i = 0; i < 4; ++i) { 
     wheels[i] = new Wheel(wheelSize); } } ~Car() { 
     for (int i = 0; i < 4; ++i) { 
     delete wheels[i]; } } const string& getModel() const { 
     return model; } const Wheel* getWheel(int index) const { 
     if (index >= 0 && index < 4) { 
     return wheels[index]; } else { 
     return nullptr; } } }; // 定义跑车类,继承自汽车类 class SportsCar : public Car { 
     private: bool turbo; public: SportsCar(const string& m, int wheelSize, bool t) : Car(m, wheelSize), turbo(t) { 
    } bool hasTurbo() const { 
     return turbo; } }; int main() { 
     // 创建跑车对象 SportsCar mySportsCar("Ferrari", 20, true); // 输出跑车信息及轮子信息 cout << "Sports Car Model: " << mySportsCar.getModel() << endl; cout << "Has Turbo: " << (mySportsCar.hasTurbo() ? "Yes" : "No") << endl; for (int i = 0; i < 4; ++i) { 
     cout << "Wheel " << i + 1 << " Size: " << mySportsCar.getWheel(i)->getSize() << " inches" << endl; } return 0; } 

6 实现关系

#include <iostream> // 定义交通工具接口 class Transportation { 
     public: virtual void move() = 0; // 抽象方法,表示交通工具的移动操作 }; // 汽车类实现了交通工具接口 class Car : public Transportation { 
     public: void move() override { 
     std::cout << "Car is moving on the road." << std::endl; } }; // 船类实现了交通工具接口 class Ship : public Transportation { 
     public: void move() override { 
     std::cout << "Ship is sailing on the sea." << std::endl; } }; int main() { 
     Car car; Ship ship; // 通过实现了接口的对象调用接口方法 car.move(); ship.move(); return 0; } 

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/126091.html

(0)
上一篇 2025-09-21 18:15
下一篇 2024-12-07 07:00

相关推荐

发表回复

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

关注微信