Types of relationships between classes: is-a, has-a, uses. Examples. Aggregation. Composition
Contents
- 1. What types of relationships exist between classes?
- 2. An example of the simplest type of is-a relationship (inheritance)
- 3. Relationship between classes of has-a type
- Related topics
Search other websites:
1. What types of relationships exist between classes?
Two types of relationships are possible between classes:
- 1. Relationship type is-a (is-a relationship). In this case, one class is a subspecies of another class. In other words, one class expands the capabilities of another class. This type is based on the use of the inheritance mechanism.
- 2. A relations in which there is a relationship between two classes. This relationship is divided into two subtypes:
- 2.1. Relationship of type has-a (has-a relationship). In this case, one or more objects of another class are declared in the class. There is also a division: aggregation, composition. If nested objects can exist independently of the class (they are not an integral part of the class), then this is aggregation. If nested objects (an object) supplement the class in such a way that the existence of a class is inconceivable without these objects, then this is a composition or union;
- 2.2. A relation of type uses (class “uses a different class). This is a generalized relation in which different forms of using one class by another are possible. If two classes are declared in a program, then optionally one class must contain an instance of another class. A class can use only some method of another class, a class can access the name of another class (use the name), a class can use the data field of another class, etc. You can read more about using the relationship type uses here.
⇑
2. An example of the simplest type of is-a relationship (inheritance)
The example demonstrates the implementation of the is-a relationship. Such relationship is necessary when it is necessary to modify (expand) an existing program code (class).
Let a class Point be defined that describes a point on the coordinate plane. The following items are implemented in the class:
- internal fields x, y;
- constructor with two parameters;
- a constructor without parameters that initialize the class fields with coordinates (0; 0);
- X, Y properties to access the internal fields x, y of the class;
- the LengthOrigin() method, which determines the length from the point (x; y) to the origin;
- method Print(), which displays the value of the fields x, y.
The next step is the need to extend the Point class with a new color element that defines the color of a point on the coordinate plane. In order not to correct the code (sometimes this is impossible) of the Point class, it is enough to implement the new ColorPoint class, which inherits (extends) the Point class and adds color to it.
In this example, the inherited ColorPoint class implements elements that complement (extend) the capabilities of the Point class:
- internal hidden field color – color of the point, which is obtained from the Colors enumeration;
- constructor with 3 parameters, initializing the value of the point with coordinates (x; y) and color value;
- property Color that implements access to the internal color field;
- The Print() method, which displays the color value and x, y coordinates of the Color base class. The method calls the Print() method of the base class of the same name.
The text of the program is as follows.
using System; using static System.Console; namespace ConsoleApp1 { // An enumeration defining a color palette, // required for use in the ColorPoint class enum Colors { Black = 0, Green = 1, Yellow = 2, Red = 3, Blue = 4 }; // Base class Point class Point { // 1. Internal fields of class - coordinates x, y private double x, y; // 2. Class constructors // 2.1. Constructor with 2 parameters - main constructor public Point(double x, double y) { this.x = x; this.y = y; } // 2.2. Constructor without parameters public Point() : this(0, 0) { } // 3. Properties X, Y public double X { get { return x; } set { x = value; } } public double Y { get { return y; } set { y = value; } } // 4. Method LengthOrigin() public double LengthOrigin() { // Pythagorean theorem return Math.Sqrt(x * x + y * y); } // 5. Method Print() public void Print() { WriteLine($"x = {x}, y = {y}"); } } // Inherited class ColorPoint class ColorPoint : Point { // 1. Hidden field - the color of point private Colors color; // 2. Constructor with 3 parameters public ColorPoint(double x, double y, Colors color) : base(x, y) { this.color = color; } // 3. Property Color public Colors Color { get { return color; } set { if (color >= 0) color = value; else color = 0; } } // 4. Method Print() void Print() { // Invoke method of base class base.Print(); // Display color Write("color = "); switch(color) { case Colors.Black: WriteLine("Black"); break; case Colors.Blue: WriteLine("Blue"); break; case Colors.Green: WriteLine("Green"); break; case Colors.Red: WriteLine("Red"); break; case Colors.Yellow: WriteLine("Yellow"); break; } } } class Program { static void Main(string[] args) { // Demonstration of Point class WriteLine("Demo Point:"); Point pt = new Point(3, 5); pt.Print(); double len = pt.LengthOrigin(); WriteLine("LengthOrigin = {0:f2}", len); // Demonstration of ColorPoint class WriteLine("Demo ColorPoint"); ColorPoint cp = new ColorPoint(1, 3, Colors.Green); cp.Print(); } } }
The result of the program
Demo Point: x = 3, y = 5 LengthOrigin = 5.83 Demo ColorPoint x = 1, y = 3
⇑
3. Relationship between classes of has-a type
With a has-a relationship, a class contains one or more objects (instances) of another class. There are two varieties of a has-a relationship:
- aggregation. This is the case when one or more nested objects is not part of the class, that is, the class can exist without these objects. A class can contain any number of such objects (even 0). See the examples below;
- composition. In this case, one or more nested objects is part of the class, that is, without these objects, the logical existence of the class itself is impossible.
Examples of classes in which the aggregation approach is implemented:
- the CarPark class can contain arrays (lists) of instances of the classes Car, Motorcycle, Bus. If at any moment in time there will not be a single car in the parking lot, the parking lot will continue to function;
- the Figures class can contain arrays of instances of the classes Rectangle, Triangle, Circle;
- the House class can contain a different number of objects of the Table, TVSet, Bed classes, etc.
Examples of interactions between classes that relate to composition:
-
- the Car class must contain one instance of the Engine class and four instances of the Wheel class. Instances of the Engine and Wheel classes are an integral part of the Car. If you remove one of these instances, the Car will not function and, as a result, the Car class will not work;
- the House class must contain an instance of the Roof class and four instances of the Wall class;
- the Triangle class (a triangle on the coordinate plane) contains three instances of the Point class.
⇑
3.1. Aggregation for has-a relationship type. Example
In the case of aggregation, a class contains many (one or more) objects of other classes that are not part of this class.
Example. The Figures class contains an array of Point classes and an array of Line classes. The number of elements in arrays can be arbitrary, even equal to 0. This means that the Figures class can exist without existing instances of the Point or Line classes. This type of interaction between classes is called aggregation.
The text of the demo example is as follows.
using System; using static System.Console; namespace ConsoleApp1 { // Aggregation // 1. Class that describes the point class Point { // Internal fields of class public double x; public double y; } // 2. Class that describes a line class Line { public Point pt1 = null; public Point pt2 = null; } // 3. A class that describes an array of figures class Figures { // 1. Internal fields of class public Point[] points; // array of points public Line[] lines; // array of lines // 2. Class constructor public Figures() { points = null; lines = null; } // 3. Method for displaying array items on the screen public void Print() { WriteLine("Array points:"); for (int i = 0; i < points.Length; i++) { WriteLine("x = {0}, y = {1}", points[i].x, points[i].y); } WriteLine("Array lines:"); for (int i=0; i<lines.Length; i++) { WriteLine("pt1.x = {0}, pt1.y = {1}", lines[i].pt1.x, lines[i].pt1.y); WriteLine("pt2.x = {0}, pt2.y = {1}", lines[i].pt2.x, lines[i].pt2.y); } } } class Program { static void Main(string[] args) { // Demonstration of aggregation using the Figures, Point, Line Classes // 1. Create an instance of Figures class Figures fg = new Figures(); // 2. Create an array of 5 points, which are objects of class Point // of instance of Figures class // 2.1. Allocate memory for 5 array items fg.points = new Point[5]; // 2.2. Allocate memory for each array item // and fill it for (int i = 0; i < fg.points.Length; i++) { fg.points[i] = new Point(); fg.points[i].x = i * i; fg.points[i].y = i * i * i; } // 3. Create an array of 3 lines // 3.1. Allocate memory for 3 array items fg.lines = new Line[3]; // 3.2. Allocate memory for each array item // and fill it for (int i = 0; i < fg.lines.Length; i++) { fg.lines[i] = new Line(); fg.lines[i].pt1 = new Point(); fg.lines[i].pt2 = new Point(); fg.lines[i].pt1.x = i; fg.lines[i].pt1.y = i * 2; fg.lines[i].pt2.x = i * 3; fg.lines[i].pt2.y = i * i; } // 4. Display an array of points and lines on the screen fg.Print(); } } }
The result of the program
Array points: x = 0, y = 0 x = 1, y = 1 x = 4, y = 8 x = 9, y = 27 x = 16, y = 64 Array lines: pt1.x = 0, pt1.y = 0 pt2.x = 0, pt2.y = 0 pt1.x = 1, pt1.y = 2 pt2.x = 3, pt2.y = 1 pt1.x = 2, pt1.y = 4 pt2.x = 6, pt2.y = 4
⇑
3.2. Composition for has-a relationship type. Example
Consider the Line class, which describes a line based on two points. Points are described by the Point class. The Line class contains 2 instances of the Point classes. Without these instances (objects), the Line class cannot exist, since both instances form part of the line (extreme points of the line). Thus, both instances of the Point class are part of the Line class. This type of interaction is called a composition or a union.
A fragment of the example is as follows.
... // Composition // 1. Class that describes a point class Point { // Internal fields public double x; public double y; } // 2. A fragment of the example is as follows. class Line { // The internal fields of a class are instances (objects) of the Point class. // Without these fields, the Line class does not make sense, which means // the pt1, pt2 fields complement the Line class (is part of the Line class), // it is a composition. public Point pt1 = null; public Point pt2 = null; } ...
⇑
Related topics
- The relationship between classes of type uses (the class uses another class). Examples
- Inheritance. Basic concepts. Advantages and disadvantages. General form. The simplest examples. Access modifier protected
⇑