Polymorphism: Difference between revisions

From Rosetta Code
Content added Content deleted
(→‎[[C]]: Moved C programming example to Polymorphism (C))
No edit summary
Line 457: Line 457:
}
}
}
}

==[[Pop11]]==
[[Category:Pop11]]

When class is defined in Pop11 it automatically defines default
constructors, slot accessors and copy operations. So it is enough
to define classes and the print method.

uses objectclass;
define :class Point;
slot x = 0;
slot y = 0;
enddefine;
define :class Circle;
slot x = 0;
slot y = 0;
slot r = 1;
enddefine;
define :method print(p : Point);
printf('Point(' >< x(p) >< ', ' >< y(p) >< ')\n');
enddefine;
define :method print(p : Circle);
printf('Circle(' >< x(p) >< ', ' >< y(p) >< ', ' >< r(p) >< ')\n');
enddefine;

To test we can use the following code:

;;; Initialize variables using default constructors
lvars instance1 = newPoint();
lvars instance2 = newCircle();
;;; Use print method
print(instance1);
print(instance2);

Revision as of 18:15, 12 May 2007

Task
Polymorphism
You are encouraged to solve this task according to the task description, using any language you may know.

Create two classes Point(x,y) and Circle(x,y,r) with a polymorphic function print, accessors for (x,y,r), copy constructor, assignment and destructor and every possible default constructors

Ada

This example is constructed using a parent package and a child package. The parent package defines the Point type. The child package defines the Circle type.

package Shapes is
   type Point is tagged private;
   procedure Print(Item : in Point);
   function Setx(Item : in Point; Val : Integer) return Point;
   function Sety(Item : in Point; Val : Integer) return Point;
   function Getx(Item : in Point) return Integer;
   function Gety(Item : in Point) return Integer;
   function Create return Point;
   function Create(X : Integer) return Point;
   function Create(X, Y : Integer) return Point;
  
private
   type Point is tagged record
      X : Integer := 0;
      Y : Integer := 0;
   end record;
end Shapes;
with Ada.Text_Io; use Ada.Text_Io;

package body Shapes is

   -----------
   -- Print --
   -----------

   procedure Print (Item : in Point) is
   begin
      Put_line("Point");
   end Print;

   ----------
   -- Setx --
   ----------

   function Setx (Item : in Point; Val : Integer) return Point is
   begin
      return (Val, Item.Y);
   end Setx;

   ----------
   -- Sety --
   ----------

   function Sety (Item : in Point; Val : Integer) return Point is
   begin
      return (Item.X, Val);
   end Sety;

   ----------
   -- Getx --
   ----------

   function Getx (Item : in Point) return Integer is
   begin
      return Item.X;
   end Getx;

   ----------
   -- Gety --
   ----------

   function Gety (Item : in Point) return Integer is
   begin
      return Item.Y;
   end Gety;

   ------------
   -- Create --
   ------------

   function Create return Point is
   begin
      return (0, 0);
   end Create;

   ------------
   -- Create --
   ------------

   function Create (X : Integer) return Point is
   begin
      return (X, 0);
   end Create;

   ------------
   -- Create --
   ------------

   function Create (X, Y : Integer) return Point is
   begin
      return (X, Y);
   end Create;

end Shapes;

The following is the child package defining the Circle type.

package Shapes.Circles is
   type Circle is new Point with private;
   procedure Print(Item : Circle);
   function Setx(Item : Circle; Val : Integer) return Circle;
   function Sety(Item : Circle; Val : Integer) return Circle;
   function Setr(Item : Circle; Val : Integer) return Circle;
   function Getr(Item : Circle) return Integer;
   function Create(P : Point) return Circle;
   function Create(P : Point; R : Integer) return Circle;
   function Create(X : Integer) return Circle;
   function Create(X : Integer; Y : Integer) return Circle;
   function Create(X : Integer; Y : Integer; R : Integer) return Circle;
   function Create return Circle;
private
   type Circle is new Point with record
      R : Integer := 0;
   end record;
end Shapes.Circles;
with Ada.Text_Io; use Ada.Text_IO;

package body Shapes.Circles is

   -----------
   -- Print --
   -----------

   procedure Print (Item : Circle) is
   begin
      Put_line("Circle");
   end Print;

   ----------
   -- Setx --
   ----------

   function Setx (Item : Circle; Val : Integer) return Circle is
   begin
      return (Val, Item.Y, Item.R);
   end Setx;

   ----------
   -- Sety --
   ----------

   function Sety (Item : Circle; Val : Integer) return Circle is
      Temp : Circle := Item;
   begin
      Temp.Y := Val;
      return Temp;
   end Sety;

   ----------
   -- Setr --
   ----------

   function Setr (Item : Circle; Val : Integer) return Circle is
   begin
      return (Item.X, Item.Y, Val);
   end Setr;

   ----------
   -- Getr --
   ----------

   function Getr (Item : Circle) return Integer is
   begin
      return Item.R;
   end Getr;

   ------------
   -- Create --
   ------------

   function Create (P : Point) return Circle is
   begin
      return (P.X, P.Y, 0);
   end Create;

   ------------
   -- Create --
   ------------

   function Create (P : Point; R : Integer) return Circle is
   begin
      return (P.X, P.Y, R);
   end Create;

   ------------
   -- Create --
   ------------

   function Create (X : Integer) return Circle is
   begin
      return (X, 0, 0);
   end Create;

   ------------
   -- Create --
   ------------

   function Create (X : Integer; Y : Integer) return Circle is
   begin
      return (X, Y, 0);
   end Create;

   ------------
   -- Create --
   ------------

   function Create (X : Integer; Y : Integer; R : Integer) return Circle is
   begin
      return (X, Y, R);
   end Create;

   ------------
   -- Create --
   ------------

   function Create return Circle is
   begin
      return (0, 0, 0);
   end Create;

end Shapes.Circles;

The following procedure is an entry point for a program, serving the same purpose as the main function in C.

with Shapes.Circles; use Shapes.Circles;
use Shapes;

procedure Shapes_Main is
   P : Point;
   C : Circle;
begin
   Print(P);
   Print(C);
end Shapes_Main;


BASIC

C

C++

Compiler: GCC, Visual C++, BCC, Watcom

 class Point
 {
   protected:
     int x, y;
   public:
     Point(int x0 = 0, int y0 = 0) : x(x0), y(y0) {}
     Point(const Point& p) : x(p.x), y(p.y) {}
     virtual ~Point() {}
     const Point& operator=(const Point& p)
     {
       if(this != &p)
       {
         x = p.x;
         y = p.y;
       }
       return *this;
     }
     int getX() { return x; }
     int getY() { return y; }
     int setX(int x0) { x = x0; }
     int setY(int y0) { y = y0; }
     virtual void print() { printf("Point\n"); }
 };
 class Circle : public Point
 {
   private:
     int r;
   public:
     Circle(Point p, int r0 = 0) : Point(p), r(r0) {}
     Circle(int x0 = 0, int y0 = 0, int r0 = 0) : Point(x0, y0), r(r0) {}
     virtual ~Circle() {}
     const Circle& operator=(const Circle& c)
     {
       if(this != &c)
       {
         x = c.x;
         y = c.y;
         r = c.r;
       }
       return *this;
     }
     int getR() { return r; }
     int setR(int r0) { r = r0; }
     virtual void print() { printf("Circle\n"); }
 };
 int main()
 {
   Point* p = new Point();
   Point* c = new Circle();
   p->print();
   c->print();     
   return 0;
 }

Pattern: Curiously Recurring Template Pattern

Compiler: GCC, Visual C++, BCC, Watcom

 // CRTP: Curiously Recurring Template Pattern
 template <typename Derived>
 class PointShape
 {
 protected:
   int x, y;
 public:
   PointShape(int x0, int y0) : x(x0), y(y0) { }
   ~PointShape() { }
   int getX() { return x; }
   int getY() { return y; }
   int setX(int x0) { x = x0; }
   int setY(int y0) { y = y0; }
   // compile-time virtual function
   void print() { reinterpret_cast<const Derived*>(this)->printType(); }
 };
 class Point : public PointShape<Point>
 {
 public:
   Point(int x0 = 0, int y0 = 0) : PointShape(x0, y0) { }
   Point(const Point& p) : PointShape(p.x, p.y) { }
   ~Point() {}
   const Point& operator=(const Point& p)
   {
     if(this != &p)
     {
       x = p.x;
       y = p.y;
     }
     return *this;
   }
   void printType() { printf("Point\n"); }
 };
 class Circle : public PointShape<Circle>
 {
 private:
   int r;
 public:
   Circle(int x0 = 0, int y0 = 0, int r0 = 0) : PointShape(x0, y0), r(r0) { }
   Circle(Point p, int r0 = 0) : PointShape(p.x, p.y), r(r0) { }
   ~Circle() {}
   const Circle& operator=(const Circle& c)
   {
     if(this != &c)
     {
       x = c.x;
       y = c.y;
       r = c.r;
     }
     return *this;
   }
   int getR() { return r; }
   int setR(int r0) { r = r0; }
   void printType() { printf("Circle\n"); }
 };
 int main()
 {
   Point* p = new Point();
   Point* c = new Circle();
   p->print();
   c->print();
   return 0;
 }

C#

 using System;
 class Point
 {
   protected int x, y;
   public Point() { this(0); }
   public Point(int x0) : this(x0,0) { }
   public Point(int x0, int y0) { x = x0; y = y0; }
   public int getX() { return x; }
   public int getY() { return y; }
   public int setX(int x0) { x = x0; }
   public int setY(int y0) { y = y0; }
   public void print() { System.Console.WriteLine("Point"); }
 }
 public class Circle : Point
 {
   private int r;
   public Circle(Point p) : this(p,0) { }
   public Circle(Point p, int r0) : base(p) { r = r0; }
   public Circle() : this(0) { }
   public Circle(int x0) : this(x0,0) { }
   public Circle(int x0, int y0) : this(x0,y0,0) { }
   public Circle(int x0, int y0, int r0) : base(x0,y0) { r = r0; }
   public int getR() { return r; }
   public int setR(int r0) { r = r0; }
   public override void print() { System.Console.WriteLine("Circle"); }
   public static void main(String args[])
   {
     Point p = new Point();
     Point c = new Circle();
     p.print();
     c.print();
   }
 }

Java

class Point
{
  protected int x, y;
  public Point() { this(0); }
  public Point(int x0) { this(x0,0); }
  public Point(int x0, int y0) { x = x0; y = y0; }
  public int getX() { return x; }
  public int getY() { return y; }
  public int setX(int x0) { x = x0; }
  public int setY(int y0) { y = y0; }
  public void print() { System.out.println("Point"); }
}
public class Circle extends Point
{
  private int r;
  public Circle(Point p) { this(p,0); }
  public Circle(Point p, int r0) { super(p); r = r0; }
  public Circle() { this(0); }
  public Circle(int x0) { this(x0,0); }
  public Circle(int x0, int y0) { this(x0,y0,0); }
  public Circle(int x0, int y0, int r0) { super(x0,y0); r = r0; }
  public int getR() { return r; }
  public int setR(int r0) { r = r0; }
  public void print() { System.out.println("Circle"); }
  public static void main(String args[])
  {
    Point p = new Point();
    Point c = new Circle();
    p.print();
    c.print();     
  }
}

Pop11

When class is defined in Pop11 it automatically defines default constructors, slot accessors and copy operations. So it is enough to define classes and the print method.

uses objectclass;
define :class Point;
    slot x = 0;
    slot y = 0;
enddefine;

define :class Circle;
    slot x = 0;
    slot y = 0;
    slot r = 1;
enddefine;

define :method print(p : Point);
    printf('Point(' >< x(p) >< ', ' >< y(p) >< ')\n');
enddefine;

define :method print(p : Circle);
    printf('Circle(' >< x(p) >< ', ' >< y(p) >< ', ' >< r(p) >< ')\n');
enddefine;

To test we can use the following code:

;;; Initialize variables using default constructors
lvars instance1 = newPoint();
lvars instance2 = newCircle();
;;; Use print method
print(instance1);
print(instance2);