Talk:Polymorphism: Difference between revisions

From Rosetta Code
Content added Content deleted
(No conceptual error)
(Circle and Point both deriving from Printable looks better to me)
Line 68: Line 68:
Of course in that case it would make sense to add a few more functions to Shape (e.g. a move function, or a function returning a bounding box). --[[User:Ce|Ce]] 08:26, 25 February 2007 (EST)
Of course in that case it would make sense to add a few more functions to Shape (e.g. a move function, or a function returning a bounding box). --[[User:Ce|Ce]] 08:26, 25 February 2007 (EST)
: The relation ''is-a'' is a notion of Liskov substitutability principle [LSP]. It is not necessarily related to inheritance and dynamic polymorphism. Sometimes the relation between types keeping all properties of the type (defined in some definite technical sense) is called '''LSP-subtyping''', and '''subclassing''', the latter, more loose relation. So-called LSP circle-ellipse controversy shows that the LSP notion of subtyping is practically (and theoretically too) unusable. Programming languages tend to more pragmatical "subclassing." --[[User:Dmitry-kazakov|Dmitry-kazakov]] 11:39, 3 November 2008 (UTC)
: The relation ''is-a'' is a notion of Liskov substitutability principle [LSP]. It is not necessarily related to inheritance and dynamic polymorphism. Sometimes the relation between types keeping all properties of the type (defined in some definite technical sense) is called '''LSP-subtyping''', and '''subclassing''', the latter, more loose relation. So-called LSP circle-ellipse controversy shows that the LSP notion of subtyping is practically (and theoretically too) unusable. Programming languages tend to more pragmatical "subclassing." --[[User:Dmitry-kazakov|Dmitry-kazakov]] 11:39, 3 November 2008 (UTC)

:'''Agree''' Circle derived from Point is poor design in this case, which might confuse the issue for the casual reader. The fix of having a common Shape subclass or interface looks much better to me. (In fact "Printable" would be a better name in the example above.) If you want to show off [[Inheritance]], perhaps split it into a different task. --[[User:IanOsgood|IanOsgood]] 13:01, 3 November 2008 (UTC)

Revision as of 13:01, 3 November 2008

Hi, I think there's a big conceptual error in the code examples: Almost all of them derive a Circle class from a Point class. This is IMHO conceptually wrong; derivation would mean that a circle is-a point, which is clearly not the case. You wouldn't normally pass circles to functions expecting points (say, a function returning the straight line through two points).

The task, as described, doesn't demand to make that error (although I suspect that whoever wrote that task had this wrong derivation in mind).

A conceptually clean implementation of the task could be (taking C++ as example):

#include <ostream>

class Shape;
{
public:
  virtual void print(std::ostream& os) const = 0;
};

std::ostream& operator<<(std::ostream& os, Shape const& s)
{
  s.print(os);
  return os;
}

class Point: public Shape
{
public:
  Point(int x = 0, int y = 0);
  int x() const;
  int y() const;
  void print() const;
private:
  int xpos, ypos;
};

Point::Point(int x, int y):
  xpos(x),
  ypos(y)
{
}

int Point::x() const
{
  return xpos;
}

int Point::y() const
{
  return ypos;
}

void Point::print(std::ostream& os) const
{
  os << "Point(" << posx << ", " << posy << ")";
}

class Circle: public Shape
{
public:
  Circle(Point const& c, int r);
  Point center() const; // Ok, not demanded by task, but makes sense
  int center_x() const; // not a good idea, but demanded by task
  int center_y() const; // dito
  int r();
  void print(std::ostream& os);
private:
  Point center;
  int radius;
};

// etc.

Of course in that case it would make sense to add a few more functions to Shape (e.g. a move function, or a function returning a bounding box). --Ce 08:26, 25 February 2007 (EST)

The relation is-a is a notion of Liskov substitutability principle [LSP]. It is not necessarily related to inheritance and dynamic polymorphism. Sometimes the relation between types keeping all properties of the type (defined in some definite technical sense) is called LSP-subtyping, and subclassing, the latter, more loose relation. So-called LSP circle-ellipse controversy shows that the LSP notion of subtyping is practically (and theoretically too) unusable. Programming languages tend to more pragmatical "subclassing." --Dmitry-kazakov 11:39, 3 November 2008 (UTC)
Agree Circle derived from Point is poor design in this case, which might confuse the issue for the casual reader. The fix of having a common Shape subclass or interface looks much better to me. (In fact "Printable" would be a better name in the example above.) If you want to show off Inheritance, perhaps split it into a different task. --IanOsgood 13:01, 3 November 2008 (UTC)