dog->createCat()
несёт горькую иронию, демонстрирующую, что от осинки не рождает апельсинка. Если очень уж хочется создать плохую иерархию типов, то лучше использовать JS. class Wolf {}
class Hound extends Wolf {}
class Pug extends Wolf {}
Wolf someDog = new Pug();
// Так можно
Pug pug = (Pug) someDog;
// А так нельзя
Hound hound = (Hound) someDog;