Polymorphism: Difference between revisions
Content added Content deleted
(Changed formatting, removed "TODO" entries. *every* language is "TODO") |
(→[[BASIC]]: Moved BASIC example to Polymorphism (BASIC) due to size) |
||
Line 242: | Line 242: | ||
==[[BASIC]]== |
==[[BASIC]]== |
||
[[Category:BASIC]] |
[[Category:BASIC]] |
||
'''Interpeter:''' [[QuickBasic]] 4.5, PB 7.1 |
|||
DECLARE SUB PointInit0 (pthis AS Point) |
|||
DECLARE SUB PointInit1 (pthis AS Point, x0 AS INTEGER) |
|||
DECLARE SUB PointInit2 (pthis AS Point, x0 AS INTEGER, y0 AS INTEGER) |
|||
DECLARE FUNCTION PointGetX%(pthis AS Point) |
|||
DECLARE FUNCTION PointGetY%(pthis AS Point) |
|||
DECLARE SUB PointSetX (pthis AS Point, x0 AS INTEGER) |
|||
DECLARE SUB PointSetY (pthis AS Point, y0 AS INTEGER) |
|||
DECLARE SUB PointPrint (pthis AS Point) |
|||
* See [[Polymorphism (BASIC)]] |
|||
DECLARE SUB CircleInit0 (pthis AS Circle) |
|||
DECLARE SUB CircleInit1 (pthis AS Circle, x0 AS INTEGER) |
|||
DECLARE SUB CircleInit2 (pthis AS Circle, x0 AS INTEGER, y0 AS INTEGER) |
|||
DECLARE SUB CircleInit3 (pthis AS Circle, x0 AS INTEGER, y0 AS INTEGER, r0 AS INTEGER) |
|||
DECLARE SUB CircleInitP0 (pthis AS Circle, p as Point) |
|||
DECLARE SUB CircleInitP0 (pthis AS Circle, p as Point, r0 AS INTEGER) |
|||
DECLARE FUNCTION CircleGetX%(pthis AS Circle) |
|||
DECLARE FUNCTION CircleGetY%(pthis AS Circle) |
|||
DECLARE FUNCTION CircleGetR%(pthis AS Circle) |
|||
DECLARE SUB CircleSetX (pthis AS Circle, x0 AS INTEGER) |
|||
DECLARE SUB CircleSetY (pthis AS Circle, y0 AS INTEGER) |
|||
DECLARE SUB CircleSetR (pthis AS Circle, r0 AS INTEGER) |
|||
DECLARE SUB CirclePrint (pthis AS Circle) |
|||
DECLARE SUB PolyPrint (pthis AS ANY, type%) |
|||
TYPE Point |
|||
x AS INTEGER |
|||
y AS INTEGER |
|||
END TYPE |
|||
TYPE Circle |
|||
p AS Point |
|||
r AS INTEGER |
|||
END TYPE |
|||
DIM SHARED POINT%, CIRCLE% |
|||
POINT% = 0 |
|||
CIRCLE% = 1 |
|||
DIM p AS Point |
|||
DIM c AS Circle |
|||
PointInit p |
|||
CircleInit c |
|||
REM No virtual function call possible |
|||
PointPrint p |
|||
CirclePrint c |
|||
REM Faked virtual function |
|||
PolyPrint p, POINT% |
|||
PolyPrint c, CIRCLE% |
|||
END |
|||
SUB PolyPrint (pthis AS ANY, type%) |
|||
IF (type% = CIRCLE%) THEN |
|||
CirclePrint pthis |
|||
ELSE |
|||
PointPrint pthis |
|||
END IF |
|||
END SUB |
|||
SUB PointInit0 (pthis AS Point) |
|||
pthis.x = 0 |
|||
pthis.y = 0 |
|||
END SUB |
|||
SUB PointInit1 (pthis AS Point, x0 AS INTEGER) |
|||
pthis.x = x0 |
|||
pthis.y = 0 |
|||
END SUB |
|||
SUB PointInit2 (pthis AS Point, x0 AS INTEGER, y0 AS INTEGER) |
|||
pthis.x = x0 |
|||
pthis.y = y0 |
|||
END SUB |
|||
FUNCTION PointGetX% (pthis AS Point) |
|||
PointGetX% = pthis.x |
|||
END SUB |
|||
FUNCTION PointGetY% (pthis AS Point) |
|||
PointGetY% = pthis.y |
|||
END SUB |
|||
SUB PointSetX (pthis AS Point, x0 AS INTEGER) |
|||
pthis.x = x0 |
|||
END SUB |
|||
SUB PointSetY (pthis AS Point, y0 AS INTEGER) |
|||
pthis.y = y0 |
|||
END SUB |
|||
SUB PointPrint (pthis AS Point) |
|||
PRINT "Point" |
|||
END SUB |
|||
SUB CircleInit0 (pthis AS Circle) |
|||
pthis.x = 0 |
|||
pthis.y = 0 |
|||
pthis.r = 0 |
|||
END SUB |
|||
SUB CircleInit1 (pthis AS Circle, x0 AS INTEGER) |
|||
pthis.x = x0 |
|||
pthis.y = y0 |
|||
pthis.r = 0 |
|||
END SUB |
|||
SUB CircleInit2 (pthis AS Circle, x0 AS INTEGER, y0 AS INTEGER) |
|||
pthis.x = x0 |
|||
pthis.y = y0 |
|||
pthis.r = 0 |
|||
END SUB |
|||
SUB CircleInit3 (pthis AS Circle, x0 AS INTEGER, y0 AS INTEGER, r0 AS INTEGER) |
|||
pthis.x = x0 |
|||
pthis.y = y0 |
|||
pthis.r = r0 |
|||
END SUB |
|||
SUB CircleInitP0 (pthis AS Circle, p as Point) |
|||
pthis.x = p.x |
|||
pthis.y = p.y |
|||
pthis.r = 0 |
|||
END SUB |
|||
SUB CircleInitP0 (pthis AS Circle, p as Point, r0 AS INTEGER) |
|||
pthis.x = p.x |
|||
pthis.y = p.y |
|||
pthis.r = r0 |
|||
END SUB |
|||
FUNCTION CircleGetX% (pthis AS Circle) |
|||
CircleGetX% = pthis.x |
|||
END SUB |
|||
FUNCTION CircleGetY% (pthis AS Circle) |
|||
CircleGetY% = pthis.y |
|||
END SUB |
|||
FUNCTION CircleGetR% (pthis AS Circle) |
|||
CircleGetR% = pthis.r |
|||
END SUB |
|||
SUB CircleSetX (pthis AS Circle, x0 AS INTEGER) |
|||
pthis.x = x0 |
|||
END SUB |
|||
SUB CircleSetY (pthis AS Circle, y0 AS INTEGER) |
|||
pthis.y = y0 |
|||
END SUB |
|||
SUB CircleSetR (pthis AS Circle, r0 AS INTEGER) |
|||
pthis.r = r0 |
|||
END SUB |
|||
SUB CirclePrint (pthis AS Circle) |
|||
PRINT "Circle" |
|||
END SUB |
|||
==[[C]]== |
==[[C]]== |
Revision as of 16:35, 26 February 2007
Polymorphism
You are encouraged to solve this task according to the task description, using any language you may know.
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
Compiler: GCC, MSVC, BCC, Watcom
Libraries: Standard
/* After reading this you may understand */ /* why Bjarne Stroustrup's invented C++ */ #if defined( _WIN32 ) || defined( MSC_VER ) #define FN_PTR(x) (& x) #else #define FN_PTR(x) (x) #endif
typedef struct Point { int x; int y; void (*dtor)(); /* virtual */ void (*print)(); /* virtual */ } Point;
Point* Point_new0() { Point* pthis = (Point*) malloc( sizeof( Point ) ); memset(pthis, 0, sizeof( Point ) ); pthis->dtor = FN_PTR(Point_dtor); pthis->print = FN_PTR(Point_print); }
Point* Point_new1(int x0) { Point* pthis = (Point*) malloc( sizeof( Point ) ); pthis->x = x0; pthis->y = 0; pthis->dtor = FN_PTR(Point_dtor); pthis->print = FN_PTR(Point_print); }
Point* Point_new2(int x0, int y0) { Point* pthis = (Point*) malloc( sizeof( Point ) ); pthis->x = x0; pthis->y = y0; pthis->dtor = FN_PTR(Point_dtor); pthis->print = FN_PTR(Point_print); }
void Point_delete(Point** pthis) { if(pthis && *pthis) { (*pthis)->dtor(); free(*pthis); *pthis = NULL; } }
Point* Point_copy(Point* p) { Point* pthis = (Point*) malloc( sizeof( Point ) ); memcpy(pthis, p, sizeof( Point ) ); pthis->dtor = FN_PTR(Point_dtor); pthis->print = FN_PTR(Point_print); return pthis; }
int Point_getX(Point* pthis) { return pthis->x; } int Point_getY(Point* pthis) { return pthis->y; } int Point_setX(Point* pthis, int x0) { pthis->x = x0; } int Point_setY(Point* pthis, int y0) { pthis->y = y0; } void Point_print() { printf("Point\n"); } void Point_dtor() {}
// Trick: This way Circle.x, Circle.y, Circle.r are available typedef union Circle { Point point; struct _Circle { Point point; int r; }; } Circle;
Circle* Circle_new0() { Circle* pthis = (Circle*) malloc( sizeof( Circle ) ); memset(pthis, 0, sizeof( Circle ) ); pthis->dtor = FN_PTR(Circle_dtor); pthis->print = FN_PTR(Circle_print); }
Circle* Circle_new1(int x0) { Circle* pthis = (Circle*) malloc( sizeof( Circle ) ); pthis->x = x0; pthis->y = 0; pthis->r = 0; pthis->dtor = FN_PTR(Circle_dtor); pthis->print = FN_PTR(Circle_print); }
Circle* Circle_new2(int x0, int y0) { Circle* pthis = (Circle*) malloc( sizeof( Circle ) ); pthis->x = x0; pthis->y = y0; pthis->r = 0; pthis->dtor = FN_PTR(Circle_dtor); pthis->print = FN_PTR(Circle_print); }
Circle* Circle_new3(int x0, int y0, int r0) { Circle* pthis = (Circle*) malloc( sizeof( Circle ) ); pthis->x = x0; pthis->y = y0; pthis->r = r0; pthis->dtor = FN_PTR(Circle_dtor); pthis->print = FN_PTR(Circle_print); }
Circle* Circle_newP0(Point* p) { Circle* pthis = (Circle*) malloc( sizeof( Circle ) ); pthis->x = p->x; pthis->y = p->y; pthis->r = 0; pthis->dtor = FN_PTR(Circle_dtor); pthis->print = FN_PTR(Circle_print); }
Circle* Circle_newP1(Point* p, int r0) { Circle* pthis = (Circle*) malloc( sizeof( Circle ) ); pthis->x = p->x; pthis->y = p->y; pthis->r = r0; pthis->dtor = FN_PTR(Circle_dtor); pthis->print = FN_PTR(Circle_print); }
void Circle_delete(Circle** pthis) { if(pthis && *pthis) { (*pthis)->dtor(); free(*pthis); *pthis = NULL; } }
Circle* Circle_copy(Circle* c) { Circle* pthis = (Circle*) malloc( sizeof( Circle ) ); memcpy(pthis, c, sizeof( Circle ) ); pthis->dtor = FN_PTR(Circle_dtor); pthis->print = FN_PTR(Circle_print); return pthis; }
int Circle_getX(Circle* pthis) { return pthis->x; } int Circle_getY(Circle* pthis) { return pthis->y; } int Circle_getR(Circle* pthis) { return pthis->r; } int Circle_setX(Circle* pthis, int x0) { pthis->x = x0; } int Circle_setY(Circle* pthis, int y0) { pthis->y = y0; } int Circle_setR(Circle* pthis, int r0) { pthis->r = r0; } void Circle_print() { printf("Circle\n"); } void Circle_dtor() {}
int main() { Point* p = Point_new0(); Point* c = (Point*)Circle_new0(); p->print(); c->print(); return 0; }
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(); } }