Recommended ways to handle final classes
JS
js.mdnq at gmail.com
Fri Aug 16 14:21:25 PDT 2013
On Friday, 16 August 2013 at 15:47:21 UTC, Joseph Rushton
Wakeling wrote:
> On 08/16/2013 05:40 PM, JS wrote:
>> Can you describe how this helps?
>>
>> Sure, if you use A the compiler should be able to optimize
>> method calls but you
>> can't use A in inheritance because it is a final class. e.g.,
>
> The point is, you should be able to use _A for inheritance, A
> for performance,
> and they both have the same functionality.
>
> Or am I mistaken?
You can't get them both at the same time though, which you might
just make _A final.
The whole point of inheritance is to treat derived classes as if
they were base classes.
e.g., code was designed to use class _A, you come along, extend
_A to A, but "trick" to the code to use your A(even though it
thinks it's an _A).
Now, when you use your final class A where _A's are suppose to
be, there can be no optimization made by the compiler(unless it
can determine the object really is an A).
e.g.,
class _A { void foo() { writeln(); } }
final class A : _A { }
...
_A a = new A;
...
a.foo(); // can't be inlined because a's type is not CT final.
A aa = new A;
...
aa.foo(); // can be inlined because aa's type is final(no need
for vtable)
The only difference is that a is _A and aa is A.
So when you use your final class with inheritance, it becomes
useless because it gets treated as the base class, which is not
final.
When one does
_A a = new A;
a is of type _A regardless of what we actually stick in a as far
as what the compiler see's(unless it's real smart but then, final
is not needed).
A final class is simply to stop someone from deriving from it.
The compiler can make optimizations based on this info IF it
knows that the object is from a final type.
Here is a more real world example
class Shape { }
final class fShape : Shape { }
class Rectangle : Shape { }
final class fRectangle : Rectangle { }
Shape s = new fRectangle; // useless, just use Rectangle, the
compiler will probably never know s is an fRectangle. (it might
in some cases but probably not worth it)
That is the oop way, this is not:
fShape s = new fRectangle; // invalid, fRectangle is not derived
from fShape.
// compiler knows s is a final class and can make optimizations
on it.
Because we can't assign concrete shapes to fShape(because they
have to derive from them, but can't because the class is final),
it becomes useless to use(no way to do oop).
To do oop you have to have derivation from base classes, but
final stops that. Hence your two goals(being able to use oop and
being able not to(using final) are mutually exclusive).
The only way it can be useful is if the compiler can determine if
an object is final at compile time... but if it can do this then
it doesn't need to be final in the first place(it will still be
able to inline methods).
More information about the Digitalmars-d-learn
mailing list