Sure. For the non-virtual member function, either make it final
(so the compiler can optimize out its virtuality), or templatize it, and then it's guaranteed to be non-virtual, since template functions are never virtual. In order to templatize a function with no template parameters, just give it an empty template parameter list. e.g.
void setChip(RxChip chip) {...}
becomes
void setChip()(RxChip chip) {...}
And for the virtual function, just make it protected
. At present, private
and package
are never virtual, so if you want a function to be virtual, you need to make it either public
or protected
, and by making it protected
, it's not accessible by the public API. You can't go full-bore and make it private
like you would in C++, but arguably, that doesn't really buy you anything anyway, since the overriding function can still be called by the class that it's in. So, all making it private
does is make it so that you can't call the base class version (which is normally pure virtual / abstract anyway).
However, I would point out that if all you want is contracts, D's in
and out
blocks support polymorphism. So, you may not even need NVI. At that point, you'd just have the base class function have in
and out
blocks with whatever in contracts and out contracts you want, and they'll get called when the derived function gets called. That just works for assertions that you want for pre and post-conditions, but it obviates the need for NVI in some cases.