1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
|
//---------------------------------------------------------------------
// name: polymorph.ck
// desc: example showing polymorphism using a base class and two
// subclasses that each implement their own play() function;
// a generic array of base class references is initialized
// with the more specific subclass instances; this allows
// for .play() to be called during the loop, the behavior of
// which can take on different forms depending on the specific
// type of underlying subclass.
//
// philosophically, polymorphism in programming amounts to
// a structured way to "break" the established contract between
// a type system and the programmer, allowing objects of
// apparently the same type to exhibit different behaviors.
//
// author: Ge Wang (https://ccrma.stanford.edu/~ge/)
// date: Winter 2023
//---------------------------------------------------------------------
// generic base class
class Motif
{
// default method to be potentially overridden in subclasses
fun void play()
{
<<< "base class Motif.play()", "" >>>;
}
}
// subclass that inherits from Motif
// can think of MoA as a more specific kind of Motif
class MoA extends Motif
{
// define play behavior for MoA by overriding play()
fun void play()
{
<<< "do Motif A", "" >>>;
}
}
// subclass that inherits from Motif
// can think of MoB as a more specific kind of Motif
class MoB extends Motif
{
// define play behavior for MoB by overriding play()
fun void play()
{
<<< "do Motif B", "" >>>;
}
}
// instantiate array of base class Motif references
// each element is a specific kind of Motif
[new MoA, new MoB, new MoB, new MoA] @=> Motif @ motifs[];
// array index variable
0 => int which;
// loop
while( true )
{
// will automatically call the right play() depending on
// the underlying type (MoA vs. MoB) as instantiated above
spork ~ motifs[which].play();
// advance time
300::ms => now;
// cycle which / print divider every cycel
which++; if( which >= motifs.size() )
{ 0 => which; cherr <= "--" <= IO.newline(); }
}
|