[swift-evolution] [Draft] Allow declaration of abstract functions and properties on classes
Wallacy
wallacyf at gmail.com
Thu Feb 25 05:57:52 CST 2016
There's a time I'm thinking of "Properties on Default Protocol
Implementations
<http://thread.gmane.org/gmane.comp.lang.swift.evolution/2996>" But I not
yet reached a consistent design. I am waiting for some other improvements
get ready to propose something that really works in the long run.
However I believe that all problems related to abstract classes can rightly
be dealt with by improving current protocols.
Em qua, 24 de fev de 2016 às 19:43, Evan Maloney via swift-evolution <
swift-evolution at swift.org> escreveu:
> After Thorsten reminded me yesterday that I wanted this feature too, I
> spent some time writing up proposal to allow declaration of abstract
> functions and properties on Swift classes:
>
> https://gist.github.com/emaloney/d0b5bf7dd831d4f7415c
>
> This is the first draft; all comments welcome!
>
> Thanks,
> E.
>
> ---
>
> Allow declaration of abstract functions and properties on classes
>
> - Proposal: SE-NNNN
> - Author: Evan Maloney <https://github.com/emaloney>
> - Status: *Draft*
> - Review manager: TBD
>
> <https://gist.github.com/emaloney/d0b5bf7dd831d4f7415c#introduction>
> Introduction
>
> Swift protocols are useful for the declaring interfaces that must be
> provided by conforming entities (in other words: structs, classes and enums).
> Adopters of a given protocol are free to provide any implementation they
> wish, so long as it supplies the necessary interfaces.
>
> Separating *interface* from *implementation* is widely considered to be a
> best practice in software design, and the Swift protocol is designed for
> this use-case.
> <https://gist.github.com/emaloney/d0b5bf7dd831d4f7415c#the-problem>The
> Problem
>
> Unfortunately, the protocol does not cover all of the cases where a
> developer might want to specify an interface to be implemented by another
> entity.
>
> For example, consider the class, which allows the creation of an
> inheritance hierarchy. Often, a class in a hierarchy exists merely to
> provide a common implementation to subclasses. Such classes aren't ever
> intended to be instantiated directly; only subclasses will be instantiated.
>
> To illustrate the point, imagine a view controller class that:
>
> 1. Places an animating UIActivityIndicatorView onscreen
> 2. Performs some operation to retrieve some text
> 3. Puts the text in a UITextView and places it onscreen
> 4. Hides the UIActivityIndicatorView
>
> Now imagine you had many cases in your application where you could benefit
> from such a view controller, and each case differed only in the operation
> required to retrieve the text (represented by Step 2 above).
>
> Ideally, you would be able to achieve this by declaring the interface for
> a function without needing to specify an implementation, the same way you
> would with a protocol:
>
> func retrieveText() -> String
>
> In other languages, such as C++, this concept exists in the form of an *abstract
> class*. However, Swift does not support this, so developers are forced to
> provide useless implementations such as:
>
> func retrieveText() -> String
> {
> fatalError("Subclasses must implement retrieveText()")
> }
>
> The idea here is that subclasses should always provide a retrieveText() implementation,
> and therefore the call to fatalError() should never be hit.
>
> This has a few significant downsides:
>
> 1.
>
> It forces the developer to write code that should never be executed
> under normal conditions. This seems like a waste.
> 2.
>
> Because a default implementation is provided--the one that calls
> fatalError()--the compiler has no way of knowing that the subclasses
> are supposed to provide an implementation, too.
> 3.
>
> If a subclass implementor forgets to provide a retrieveText() function,
> the error will not be caught until runtime, and not until a user navigates
> to the affected portion of the application. This may not occur until the
> application has shipped.
>
> <https://gist.github.com/emaloney/d0b5bf7dd831d4f7415c#proposed-solution>Proposed
> Solution
>
> The proposed solution involves adding support for abstract classes to
> Swift.
>
> This would entail:
>
> -
>
> Allowing functions and properties to be declared abstract. An abstract
> function or property declares the interface without specifying the
> implementation.
> -
>
> Allowing abstract classes to be defined by partially unimplemented
> protocol conformances. If a class declares conformance to a protocol
> without providing an implementation for each of that protocol's properties
> and functions, it is an abstract class.
> -
>
> Requiring classes to be explicitly declared as abstract if it has one
> or more unimplemented functions or properties.
>
> <https://gist.github.com/emaloney/d0b5bf7dd831d4f7415c#detailed-design>Detailed
> Design
> <https://gist.github.com/emaloney/d0b5bf7dd831d4f7415c#abstract-functions>Abstract
> functions
>
> Functions can be declared abstract using the abstract keyword, which must
> appear before the func keyword in the declaration. Otherwise, the
> notation is identical to how the function would be declared if it were to
> appear in a protocol:
>
> public abstract func retrieveText() -> String
>
> As long as the abstract keyword appears before the func, the order of
> appearance of the abstract keyword relative to any public, private or
> internal access modifiers is not meaningful.
>
> The following declaration is equivalent to the one above:
>
> abstract public func retrieveText() -> String
>
> <https://gist.github.com/emaloney/d0b5bf7dd831d4f7415c#abstract-properties>Abstract
> properties
>
> Abstract property declarations are identical to what would be found in a
> protocol, but are prefixed with the abstractkeyword, which must appear
> first:
>
> abstract var fileName: String { get }
> abstract var favoriteColor: UIColor { get set }
>
> As is typical with protocol declarations, var is always used and not let.
>
> <https://gist.github.com/emaloney/d0b5bf7dd831d4f7415c#abstract-protocol-conformance>Abstract
> protocol conformance
>
> A class can be made abstract by declaring conformance to a protocol that
> it does not implement fully.
>
> For example, say you had a protocol Vehicle:
>
> protocol Vehicle
> {
> var name: String { get }
> var color: UIColor { get }
> var numberOfWheels: Int { get }
> var isParked: Bool { get set }
>
> func driveTo(destination: Location) throws
> }
>
> In your code, you're able to factor out everything except the driveTo() function,
> the implementation of which is vehicle-specific. The common code goes into
> a BaseVehicle class:
>
> abstract class BaseVehicle: Vehicle
> {
> let name: String
> let color: UIColor
> let numberOfWheels: Int
> var isParked: Bool
>
> init(name: String, color: UIColor, numberOfWheels: Int, isParked: Bool = true)
> {
> self.name = name
> self.color = color
> self.numberOfWheels = numberOfWheels
> self.isParked = isParked
> }
> }
>
> The BaseVehicle class partially conforms to the Vehicle protocol: the name
> , color, numberOfWheels and isParked properties are provided, but the
> driveTo() function remains unimplemented.
>
> As a result, BaseVehicle is an abstract class and must be declared as
> such.
>
> <https://gist.github.com/emaloney/d0b5bf7dd831d4f7415c#the-abstract-class-declaration>
> The abstract class declaration
>
> A class must be declared as abstract if any of the following are true:
>
> 1. If the class declares one or more abstract functions or properties
> 2. If the class declares conformance to a protocol but does not supply
> implementations for every one of the functions and properties declared in
> that protocol.
> 3. If the class inherits from an abstract class and does not supply an
> implementation for every one of the unimplemented functions or properties.
>
> Classes are marked as abstract by placing the abstract keyword before the
> class keyword at the top of the class declaration, eg.:
>
> public abstract class MyAbstractClass
> {
> // ...code...
> }
>
> As long as the abstract keyword appears before the class, the order of
> appearance of the abstract keyword relative to any public, private or
> internal access modifiers is not meaningful.
>
> The following declaration is equivalent to the one above:
>
> abstract public class MyAbstractClass
> {
> // ...code...
> }
>
> <https://gist.github.com/emaloney/d0b5bf7dd831d4f7415c#instantiation>
> Instantiation
>
> Because an abstract class is not a complete implementation, the compiler
> will not allow instantiation of abstract classes.
>
> Attempting to instantiate an abstract class will result in a compiler
> error.
>
> <https://gist.github.com/emaloney/d0b5bf7dd831d4f7415c#impact-on-existing-code>Impact
> on Existing Code
>
> None, since this does not affect any existing constructs. Implementation
> of this proposal will not result in any code breakage.
> <https://gist.github.com/emaloney/d0b5bf7dd831d4f7415c#citations>Citations
>
> This idea has been discussed in the following swift-evolution
> <https://lists.swift.org/mailman/listinfo/swift-evolution> mailing list
> threads:
>
> - [Review] SE-0030 Property Behaviors
> <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160222/010876.html>
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160225/0c81cc66/attachment.html>
More information about the swift-evolution
mailing list