There is something odd, on how you use "virtual" on some, but not other methods. And how there is no "override" at all.
Anyway, I copied it blindly in below examples. Keep in mind that "inherited" works for none virtual methods too. So my inherited example can be made independent of what is virtual.
There are millions of discussion on the internet about multiply inheritance (MI). The conclusions go from ok to disaster. (I stick to the latter).
In any case, in most cases MI can easily be replaced by delegation. And in the long term delegation often yields the better results.
But lets first look at your example.
You are mixing several things.
MI:
TFace = class ( TSmile, TEyes );
Shorthand to avoid writing a function body:
Procedure Stop_Crying = TEyes.Stop_Crying; virtual;
The shorthand has nothing to do with MI. It could be done for normal classes to. (e.g. forward to a delegate class).
So if and when comparing, the above needs to be kept in mind. Only compare the MI. Do not mistake the other shorthands for MI, and advertise MI as better, because you like the shorthand.
Your example as delegation (with shorthands, so comparison stands)
TFace = class
FSmile: TSmile;
FEyes: TEyes;
Procedure Stop_Crying = FEyes.Stop_Crying; virtual;
end;
Of course the shorthand does not exist. So you need to write code for it.
And you also need to create FSmile and FEyes in the constructor of TFace (for that a shorthand could be found, but I would not advertise doing so).
So anyway, other than the need to create TSmile/TEyes instances (which also gives you the power to instantiate subclasses like TCrookedSmile) the above is the same amount of code.
Only with MI, if I write
procedure TFace.SomeThing;
begin
inherited Stop_Crying;
end;
It becomes complicated. Which baseclass should be called?
This is especially a problem, when you hadn't looked at the code in a couple of years, but need to work on it again.
With delegation, you always get explicit calls (calls on either FSmile or FEyes).
In conclusion, after taking out the shorthands:
Delegates and MI need a body for TFace.Stop_Crying. (or both can have the shorthand). => equal
Delegates need to create the delegates (and destroy them).
2 lines of code per delegate. But more flexibility, as delegates can be instances of subclasses.
In any case, if needs must a shorthand would be possible.
Delegates prevent you from ambiguous inherited calls.