Part 10 - Polymorphism, or Inherited Methods
| Definition: Polymorphism The ability for a new object to implement the base functionality of a parent object in a new way. |
Two keywords are used to make Polymorphism happen: virtual and override.
You need to describe a method as virtual if you want the ability to override its capabilities.
class Rectangle:
def constructor(width as single, height as single):
_width = width
_height = height
virtual def GetArea():
return _width * _height
_width as single
_height as single
class Square(Rectangle):
def constructor(width as single):
super(width, width)
override def GetArea():
return _width * _width
r = Rectangle(4.0, 6.0)
s = Square(5.0)
print r.GetArea()
print s.GetArea()
print cast(Rectangle, s).GetArea()
Note that, because Rectangle does not have a default, parameterless constructor, we must invoke Rectangle's constructor in the first line of Square's constructor (the super(width, width) part). Once again: when calling a superclass's constructor, it must be done on the first line.
24.0 25.0 25.0
Even when casted to a Rectangle, s's .GetArea() functioned like if it were a Square.
An easier example to see is this:
class Base:
virtual def Execute():
print 'From Base'
class Derived(Thing):
override def Execute():
print 'From Derived'
b = Base()
d = Derived()
print b.Execute()
print d.Execute()
print cast(Base, d).Execute()
From Base From Derived From Derived
If I were to leave out the virtual and {{override} keywords,
From Base From Derived From Base
This happens because unless the base method is virtual or abstract, the derived method cannot be declared as override.
| Recommendation Although you do not have to explicitly declare a method as override when inheriting from a virtual method, you should anyway, in case the signatures of the virtual and overriding methods do not match. |
In order to override, the base function must be declared as virtual or abstract, have the same return type, and accept the same arguments.
Polymorphism is very handy when dealing with multiple types derived from the same base.
interface IAnimal: def MakeNoise() class Dog(IAnimal): def MakeNoise(): print 'Woof' class Cat(IAnimal): def MakeNoise(): print 'Meow' class Hippo(IAnimal): def MakeNoise(): print '*Noise of a Hippo*' list = [] list.Add(Dog()) list.Add(Cat()) list.Add(Hippo()) for animal as IAnimal in list: list.MakeNoise()
Woof Meow *Noise of a Hippo*
Very handy.
Exercises
- Figure out an exercise
Go on to Part 11 - Structs

Comments (4)
Oct 15, 2005
Nicault Daniel says:
Hi, In the source code "Polymorphism with Rectangle and Square", is it an erro...Hi,
In the source code "Polymorphism with Rectangle and Square", is it an error to redefine the Rectangle constructor with only 1 parameter for square unless the ancetor as 2 parameters constructor ?
I think logical to make call to the super constructor in the ancestor, no ?
With boo 0.7.0, I get an error...
I have to rewrite the source with something like:
class Rectangle:
def constructor(width as single):
pass
def constructor(width as single, height as single):
_width = width
_height = height
virtual def GetArea():
return _width * _height
_width as single
_height as single
class Carre(Rectangle):
def constructor(width as single):
super(width, width)
//the GetArea() Pethod is no longer necessary
//use the super method...
//def GetArea():
// return _width * _width
r = Rectangle(4.0, 6.0)
s = Carre(5.0)
print r.GetArea()
print s.GetArea()
print cast(Rectangle, s).GetArea()
</pre>
Like this I think it's more correct and, It works...
Oct 17, 2005
Nicault Daniel says:
Or like here with only a call to super in the new definition of constructor... ...Or like here with only a call to super in the new definition of constructor...
class Square(Rectangle):
def constructor(longueur as single):
super(longueur, 0)
override def GetArea():
return _largeur * _largeur
Nov 07, 2005
Michel Casabianca says:
Second example should be: -8<-----------------------------------------------...Second example should be:
-
8<---------------------------------------------------------class Base:
virtual def Execute():
print 'From Base'
class Derived(Base):
override def Execute():
print 'From Derived'
b = Base()
d = Derived()
b.Execute()
d.Execute()
cast(Base, d).Execute()
-
8<---------------------------------------------------------Nov 07, 2005
Michel Casabianca says:
Third example should be: -8<------------------------------------------------...Third example should be:
-
8<-----------------------------------------------------------interface IAnimal:
def MakeNoise()
class Dog(IAnimal):
def MakeNoise():
print 'Woof'
class Cat(IAnimal):
def MakeNoise():
print 'Meow'
class Hippo(IAnimal):
def MakeNoise():
print 'Noise of a Hippo'
list = []
list.Add(Dog())
list.Add(Cat())
list.Add(Hippo())
for animal as IAnimal in list:
animal.MakeNoise()
-
8<-----------------------------------------------------------