On 5/16/22 17:10, Alain De Vos wrote:
Let's say a shape is ,a circle with a radius ,or a square with a rectangular size.
I want to pass shapes to functions, eg to draw them on the screen,
draw(myshape) or myshape.draw();
But how do i implement best shapes ?

There are many ways of achieving this but I think you are looking for the classic object-oriented (OOP) shape hierarchy. (Option 2 below.)

1) This option does not use OOP. It uses function overloading:

import std.stdio;

struct Circle {
  float radius;
}

void draw(Circle circle) {
  writeln("This circle's radius is ", circle.radius);
}

struct Rectangle {
  float width;
  float height;
}

void draw(Rectangle rectangle) {
writefln!"This rectangle's dimensions are %sx%s."(rectangle.width, rectangle.height);
}

void main() {
  draw(Circle(1.5));
  draw(Rectangle(2.5, 3.5));
}

That's very simple but it does not allow putting different types of shapes e.g. in the same array.


2) If you want to have a shape hierarchy, then you can start by defining its interface and implement that interface by concrete shape types. Drawing is ordinarily handled by member functions:

import std.stdio;

// This defines what we can do with a Shape:
interface Shape {
  void draw();
}

// This type is now a 'class' that implements Shape.
class Circle : Shape {
  float radius;

  // Classes require constructors; so here is one:
  this (float radius) {
    this.radius = radius;
  }

  // No parameter needed. This function always executes on
  // 'this' object.
  void draw() {
    writeln("This circle's radius is ", radius);
  }
}

// Similarly, a class
class Rectangle : Shape {
  float width;
  float height;

  this(float width, float height) {
    this.width = width;
    this.height = height;
  }

  void draw() {
    writefln!"This rectangle's dimensions are %sx%s."(width, height);
  }
}

// Here is the promise of polymorphism: This function takes
// a Shape but the special drawing of each shape type is
// handled automatically.
void use(Shape shape) {
  shape.draw();
}

void main() {
  // Class hierarchies allow putting different types into
  // the same array:
  Shape[] shapes;

  // Let's populate with alternating circles and rectangles
  foreach (i; 1 .. 10) {
    if  (i % 2) {
      shapes ~= new Circle(i);

    } else {
      shapes ~= new Rectangle(i, i * 2);
    }
  }

  // And finally let's use them
  foreach (shape; shapes) {
    use(shape);
  }
}

Ali

Reply via email to