It is necessary to develop a hierarchy of classes of spatial figures: a cone, a parapiped, a cube, a sphere, an ellipsoid, a cylinder. How is it better to organize, there, what class to take for the base and TP?
- Very bad answer. The inheritance relationship is essentially the "is" relationship. Therefore, the rectangle from the square should not be inherited. - dzhioev
- 3What are you going to do with the objects of your classes? As they say in the village, it depends. - BuilderC
- 2habrahabr.ru/blogs/programming/123014 get acquainted, very useful - Viacheslav
- square as a particular rectangle shape, I meant to highlight the main types of shapes and inherit marching from them. Looked at the link (the one that is in question), IMHO, it is immediately obvious that the circle is a special case of an ellipse, i.e. an ellipse with the same radius. And to distinguish the interface "body" is the wrong level of abstraction, so you can take a point, why is there .... and if you take it, so let it keep the type and name =) - Gorets
- The rectangle from the square is really not worth it. And vice versa is possible (square is a special case of a rectangle, and a ball is a special case of an ellipsoid), but why? In this question, the volumetric figures can be inherited from those flat ones for which they are the bodies of revolution. A cylinder from a rectangle, an ellipsoid from an ellipse, a cone from a triangle, etc. But without understanding the multitude of tasks for which all this requires such a development, the matter is empty. - avp
4 answers
At the very top of the hierarchy, an abstract class, let's say, a Figure with a set of virtual functions for working with objects, such as drawing and so on.
At the second level of a figure with one parameter: a cube (side) and a sphere (radius)
At the third level, figures with 2 parameters with inheritance from 1-parameter figures, for example, an ellipsoid, a cylinder and a cone are inherited from a sphere, a parallelepiped from a cube, etc.
- oneIt is usually more convenient on the contrary - to make a particular (cube) out of the general (parallelepiped). By the way, do not draw, how to get a cone from a sphere? - avp
- This is not a matter of convenience, but a matter of class members. The sphere has a 1st member = protected radius, and a cone of two members: radius and height, with the radius inheriting from the sphere. Saving space there. Not? - Barmaley
- oneWell, if the goal of designing a hierarchy of classes is to consider saving memory for data, then Yes! - avp
- It is impossible to inherit a rectangle from a square, it violates the Principle of Lisk (LSP) substitution. - Abyx
Geometric objects are one of the special cases. Take a set of flat shapes: Square - Rectangle - Parallelogram - Rhombus
In geometry, a square is a special case of a rectangle and a rhombus, a rectangle is a special case of a parallelogram, and a rhombus is a special case of a parallelogram. We will not be able to implement such a chain. OOP extends inheritance, i.e. we can add something to the heir, but we cannot cut out the excess.
In OOP (expanding functionality). A parallelogram is inherited from a rhombus or a rectangle, a rhombus is inherited from a square, a rectangle is inherited from a square. Because an instance of a derived class is also an instance of a base class, then in this context we get, for example, the following statement: any rectangle is a square. And this contradicts the geometric definition (and logic).
With solid shapes, lines, surfaces, etc. exactly the same thing.
Thus, we can select an abstract class / interface as a base class of geometric objects, for example, GeometricSolid, and define in a set of general methods for calculating the volume and surface area, all shapes have this. The figures themselves inherit from this class / interface, all on the same level . Only in this form, your model will not contradict the OOP or geometry.
For the base, you can select the interface " Π’Π΅Π»ΠΎ ". Interfaces in C++ are abstract classes.
For example, if these are classes for a visualization system, then it makes sense to declare a draw method:
class body { ... virtual void draw() = 0; ... }; Here's my solution, really for you. Take remake for yourself
#include <iostream> #include <iomanip> #include <conio.h> #include <string.h> #define M_PI 3.14159265358979323846 using namespace std; /*================================================ Π‘ΠΎΠ·Π΄Π°ΡΡ ΠΈΠ΅ΡΠ°ΡΡ
ΠΈΡ ΠΊΠ»Π°ΡΡΠΎΠ² Π’ΠΎΡΠΊΠ°-ΠΡΡΠ³-ΠΠΎΠ½ΡΡ. ΠΠΎΠ½ΡΡ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΡ ΠΌΠ΅ΡΠΎΠ΄ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΡ ΠΎΠ±ΡΠ΅ΠΌΠ°. ΠΠΎΡΠ»Π΅Π΄Π½ΠΈΠ΅ Π΄Π²Π° ΠΊΠ»Π°ΡΡΠ° Π΄ΠΎΠ»ΠΆΠ½Ρ ΠΈΠΌΠ΅ΡΡ ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΎΡΡ. ===================================================*/ class Point { //ΠΠ»Π°ΡΡ Point public: int x; int y; }; class Circle : public Point { public: float r1; //ΡΠ°Π΄ΠΈΡΡ ΠΊΡΡΠ³Π° Circle(float r1) { r1 = r1; } }; class Cone : public Circle { public: double H; double volume; Cone(double r1, double h1):Circle(r1) { H = h1; } void calculate_volume() { volume = (1.0 / 3.0) * H * M_PI; //Π€ΠΎΡΠΌΡΠ»Π° Π΄Π»Ρ Π½Π°Ρ
ΠΎΠΆΠ΄Π΅Π½ΠΈΡ ΠΎΠ±ΡΠ΅ΠΌΠ° ΠΊΠΎΠ½ΡΡΠ° } }; /*================================================ Π‘ΠΎΠ·Π΄Π°ΡΡ ΠΌΠ΅ΡΠΎΠ΄ MAIN, Π² ΠΊΠΎΡΠΎΡΠΎΠΌ ΡΠΎΠ·Π΄Π°Π΅ΡΡΡ Π΄Π²Π° ΠΊΠΎΠ½ΡΡΠ°, ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅ΡΡΡ ΠΊΠ°ΠΊΠΎΠΉ ΠΈΠ· ΠΊΠΎΠ½ΡΡΠΎΠ² ΠΌΠ΅Π½ΡΡΠ΅, Π° ΡΠ°ΠΊΠΆΠ΅ Π²Ρ
ΠΎΠ΄ΠΈΡ Π»ΠΈ ΠΌΠ΅Π½ΡΡΠΈΠΉ ΠΊΠΎΠ½ΡΡ Π² Π±ΠΎΠ»ΡΡΠΈΠΉ. Π’Π°ΠΊΠΆΠ΅ ΠΏΠΎΠΊΠ°Π·Π°ΡΡ Π²ΡΠ΅ Ρ
Π°ΡΠ°ΠΊΡΠ΅ΡΠΈΡΡΠΈΠΊΠΈ ΡΠΎΠ·Π΄Π°Π²Π°Π΅ΠΌΡΡ
ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ². ===================================================*/ void main() { setlocale(LC_ALL, "rus"); //Π½Π°ΡΡΡΠ°ΠΈΠ²Π°Π΅ΠΌ Π»ΠΎΠΊΠ°Π»Ρ setlocale(LC_NUMERIC, "C"); /*================================================ Π’Π°ΠΊΠΈΠ΅ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ, ΡΡΠΎΠ±Ρ ΠΌΠ΅Π½ΡΡΠΈΠΉ ΠΊΠΎΠ½ΡΡ ΠΏΠΎΠ»Π½ΠΎΡΡΡΡ Π²Ρ
ΠΎΠ΄ΠΈΠ» Π² Π±ΠΎΠ»ΡΡΠΈΠΉ ===================================================*/ Cone m(5, 6); //Π±ΠΎΠ»ΡΡΠΈΠΉ ΠΊΠΎΠ½ΡΡ Cone n(5, 6); //ΠΌΠ΅Π½ΡΡΠΈΠΉ ΠΊΠΎΠ½ΡΡ /*================================================ Π’Π°ΠΊΠΈΠ΅ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ, ΡΡΠΎΠ±Ρ ΠΌΠ΅Π½ΡΡΠΈΠΉ ΠΊΠΎΠ½ΡΡ Π½Π΅ Π²Ρ
ΠΎΠ΄ΠΈΠ» Π² Π±ΠΎΠ»ΡΡΠΈΠΉ ===================================================*/ //Cone m(4, 6); //Π±ΠΎΠ»ΡΡΠΈΠΉ ΠΊΠΎΠ½ΡΡ //Cone n(6, 4); //ΠΌΠ΅Π½ΡΡΠΈΠΉ ΠΊΠΎΠ½ΡΡ m.calculate_volume(); //ΡΡΠΈΡΠ°Π΅ΠΌ ΠΎΠ±ΡΠ΅ΠΌ ΠΏΠ΅ΡΠ²ΠΎΠ³ΠΎ ΠΊΠΎΠ½ΡΡΠ° n.calculate_volume(); //ΡΡΠΈΡΠ°Π΅ΠΌ ΠΎΠ±ΡΠ΅ΠΌ Π²ΡΠΎΡΠΎΠ³ΠΎ ΠΊΠΎΠ½ΡΡΠ° cout Β« "ΠΠ±ΡΠ΅ΠΌ ΠΏΠ΅ΡΠ²ΠΎΠ³ΠΎ ΠΊΠΎΠ½ΡΡΠ° ΡΠ°Π²Π΅Π½: " Β« m.volume Β« " ΠΊΡΠ±ΠΈΡΠ΅ΡΠΊΠΈΡ
Π΅Π΄ΠΈΠ½ΠΈΡ" Β« endl; cout Β« "ΠΠ±ΡΠ΅ΠΌ Π²ΡΠΎΡΠΎΠ³ΠΎ ΠΊΠΎΠ½ΡΡΠ° ΡΠ°Π²Π΅Π½: " Β« n.volume Β« " ΠΊΡΠ±ΠΈΡΠ΅ΡΠΊΠΈΡ
Π΅Π΄ΠΈΠ½ΠΈΡ" Β« endl; cout Β« "-------------------------------------------" Β« endl; //ΠΏΡΠΎΠ²Π΅ΡΠΊΠ°, Π΅ΡΠ»ΠΈ ΠΎΠ±ΡΠ΅ΠΌΡ ΠΊΠΎΠ½ΡΡΠΎΠ² ΡΠ°Π·Π½ΡΠ΅ if (m.volume > n.volume) { cout Β« "ΠΠ΅Π½ΡΡΠΈΠΉ ΠΊΠΎΠ½ΡΡ ΠΏΠΎΠ»Π½ΠΎΡΡΡΡ Π²Ρ
ΠΎΠ΄ΠΈΡ Π² Π±ΠΎΠ»ΡΡΠΈΠΉ ΠΊΠΎΠ½ΡΡ..." Β« endl; } else if (m.volume = n.volume) { cout Β« "ΠΠ±ΡΠ΅ΠΌΡ Π΄Π²ΡΡ
ΠΊΠΎΠ½ΡΡΠΎΠ² ΡΠ°Π²Π½Ρ" Β« endl;; } else { cout Β« "ΠΠ΅Π½ΡΡΠΈΠΉ ΠΊΠΎΠ½ΡΡ Π½Π΅ Π²Ρ
ΠΎΠ΄ΠΈΡ Π² Π±ΠΎΠ»ΡΡΠΎΠΉ ΠΊΠΎΠ½ΡΡ..." Β« endl; } cout Β« "--------------------------------------------" Β« endl; cout Β« "ΠΡΠ²ΠΎΠ΄ΠΈΠΌ Π²ΡΠ΅ Ρ
Π°ΡΠ°ΠΊΡΠ΅ΡΠΈΡΡΠΈΠΊΠΈ ΡΠΎΠ·Π΄Π°Π½Π½ΡΡ
ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² Π½Π° ΡΠΊΡΠ°Π½: " Β« endl; cout Β« setw(25) Β« "Π Π°Π΄ΠΈΡΡ ΠΏΠ΅ΡΠ²ΠΎΠ³ΠΎ ΠΊΠΎΠ½ΡΡΠ°: " Β« m.r1 Β« setprecision(6) Β« endl; cout Β« setw(25) Β« "ΠΡΡΠΎΡΠ° ΠΏΠ΅ΡΠ²ΠΎΠ³ΠΎ ΠΊΠΎΠ½ΡΡΠ°: " Β« mH Β« endl; cout Β« setw(25) Β« "Π Π°Π΄ΠΈΡΡ Π²ΡΠΎΡΠΎΠ³ΠΎ ΠΊΠΎΠ½ΡΡΠ°: " Β« n.r1 Β« setprecision(6) Β« endl; cout Β« setw(25) Β« "ΠΡΡΠΎΡΠ° Π²ΡΠΎΡΠΎΠ³ΠΎ ΠΊΠΎΠ½ΡΡΠ°: " Β« nH Β« endl; system("pause"); }