On Friday, 4 January 2019 at 02:13:27 UTC, Neia Neutuladh wrote:
I can't think of a single class system that works like that.
C++, Java, C#, Dart, and TypeScript all work like D here.
GObject in C works like D.
In the example below, the "2" of B.foo is printed only once.
Independently of the cast type, after degrading a B to an A the
degraded object behaves like an A.
´´´ C++ ´´´
#include <iostream>
class A
{
public:
int foo(){return 1;}
};
class B : public A
{
public:
int foo(){return 2;}
};
void performFoo(A *a)
{
std::cout << a->foo() << std::endl;
}
int main() {
auto a = new A();
auto b = new B();
std::cout << a->foo() << std::endl;
std::cout << b->foo() << std::endl;
std::cout << dynamic_cast<A*>(b)->foo() << std::endl;
std::cout << static_cast<A*>(b)->foo() << std::endl;
std::cout << reinterpret_cast<A*>(b)->foo() << std::endl;
performFoo(a);
performFoo(b);
return 0;
}
´´´
The point of OOP is that a bundle of data has particular ways
of dealing with it. B has different data (at least
theoretically), and that data has different ways of working
with it. So if casting to a base class changed something to use
the base class's behavior, you'd get bugs almost anywhere you
used inheritance, since the derived class's data isn't being
modified properly.
Now I have the feeling, I'm missing something elementary... sorry
for this...
But take the classic example of OOP of an Animal and a Dog:
Animal.
Let the animal implement some default move and eat behavior.
Let the dog override the move method and implement bark.
If you degrade the dog to the animal by casting it should still
be able to move and eat, but not bark.
This should always be true for inherited objects as the base
classes define enough content to manage proper behavior of their
own. (Given they are not abstract, a function is not virtual and
so on...)