Inheritance
Inheritance
HolyC supports a form of class inheritance. A class can embed another class as its first member, and in some HolyC implementations, a child class can be used wherever the parent class is expected.
Embedding (Composition)
The most reliable pattern is explicit embedding — include the parent class as a named member:
class Animal {
U8 *name;
U8 *sound;
};
class Dog {
Animal base;
U8 *breed;
};
Dog d;
d.base.name = "Rex";
d.base.sound = "Woof";
d.breed = "Labrador";
Print("%s (%s) says %s\n", d.base.name, d.breed, d.base.sound);
// Rex (Labrador) says Woof
Polymorphism via Pointers
By casting a Dog * to an Animal *, you can pass different "subtypes" to the same function:
class Animal {
U8 *name;
U8 *sound;
};
U0 Speak(Animal *a) {
Print("%s says %s\n", a->name, a->sound);
}
Animal cat;
cat.name = "Cat";
cat.sound = "Meow";
Animal dog;
dog.name = "Dog";
dog.sound = "Woof";
Speak(&cat);
Speak(&dog);
This works because both cat and dog are the same type (Animal), but in larger programs you would use the embedding approach and cast the pointer.
Your Task
Define an Animal class with U8 *name and U8 *sound fields. Write a U0 Speak(Animal *a) function that prints NAME says SOUND.
Create two animals: a "Cow" that says "Moo" and a "Duck" that says "Quack". Call Speak on each.
Expected output:
Cow says Moo
Duck says Quack