This is in reference to:
swift-evolution/nnnn-overridable-members-in-extensions.md at
overridable-members-in-extensions · jrose-apple/swift-evolution · GitHub
<https://github.com/jrose-apple/swift-evolution/blob/overridable-members-in-extensions/proposals/nnnn-overridable-members-in-extensions.md>
The limitation of not being able to override methods introduced by an extension
to a parent class within a child class is pretty significant and I would
propose that we find and explore a way to allow such while supporting the
original intent of this limitation.
This has become a problem for a project I’m working on when transitioning to
Swift 4. Here is a description of the problem:
Our major application has a class hierarchy of financial transaction types
similar to the following:
Transaction
Billable
Taxable
Purchase
Bill
...
Sales
Estimate
Invoice
...
Deposit
Journal Entry
...
Etc.
These are currently implemented in ObjC but have been extended in Swift. So
there are the original transaction classes in ObjC with extensions in Swift.
This combination of ObjC/Swift has been done to support modern presentation in
iOS, essentially following the MVVM approach. ‘Transaction’ has been extended
and specifies the various View Model methods each of its child classes must
implement. There are default implementations going down the Swift inheritance
tree but each child can customize (override) those methods and, many times,
calls the inherited method.
For instance, the header presentation for each transaction shows a date and
total amount but each subclass has other header elements to show: all
‘Billable’ transactions show a name and due date. Going down the chain, each
final child class provides the explicit title to be shown in the header, such
as ‘Invoice’. Further, the background color of the header is set based on the
status of the transaction. Of course, some transactions only have one state,
the default state provided by a parent class.
With this said, eliminating the ability to extend ‘Transaction’ and then
override down in each subclass’s extension was very convenient. Under the
current Swift 4 restrictions we will have to either reimplement the class
extensions in the original model (which will not be done because the model must
be ignorant of any presentation-specific requirements) or everything will have
to be moved up into a single Transaction extension and use a switch structure
based on dynamic casting as discussed in the article mentioned way above (which
corrupts ‘Transaction’ by requiring it to know intimate details about its
children, grandchildren, etc.).
It would be nice if there were some protocol-based mechanism where a parent
class could adopt that protocol (not in the original class declaration, of
course, since UI-related methods should not be polluting the model layer) and
then some extension-like mechanism allowing child classes to provide their
specific implementation of those methods.
Of course, one potential approach would be to create a similar class structure
to the model’s Transaction structure but where the new class ‘owns’ the
instance of the raw transaction. Say, something like TransactionVM with
BillableVM, PurchaseVM, etc. Of course, for each different type of transaction
presentation (full details, brief details, list summary, etc.) there would need
to be yet another ‘container’ class structure. And they wouldn’t be able to
inherit from one another for the same reason I’m blathering on here.
Of course, if there is already a more appropriate approach for solving a
problem like this, please do not hesitate to correct me as I still consider
myself pretty ‘young’ with Swift 4.
Mike
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution