[swift-evolution] [Proposal draff] abstract classes and methods

David Scrève david.screve at dlta-studio.com
Thu Jan 7 11:55:57 CST 2016


# Abstract classes and methods

* Author(s): David Scrève

## Introduction

When developing framework and reusable, we need to develop classes that are partially 
abstract with partial implementation. Protocol and protocol extensions provide this, but 
they cannot have attributes as classes have.
A partial class combines the behavior of a class with the requirement of implementing methods
in inherited class like protocols.

Swift-evolution thread: [link to the discussion thread for that proposal](https://lists.swift.org/pipermail/swift-evolution)

## Motivation
Like pure virtual methods in C++ and abtract classes in Java and C#, frameworks development 
sometimes required abstract classes facility.
An abstract class is like a regular class, but some methods/properties are not implemented 
and must be implemented in one of inherited classes.
An abstract class can inherit from other class, implements protocols and has members 
attributes as opposite from protocols.
Only some methods and properties might be abstract.
The goal of abstract classes is to encapsulate a generic behavior that may need some 
specific implementation methods which are not known in abstract class. This behavior 
requires attributes that are used by internal abstract class method.

Example : 
Considere a generic RESTClient that is included in a framework : 

```swift
class RESTClient {
    
    var timeout = 3000
    
    var url : String {
        assert(false,"Must be overriden")
        return ""
    }
    
    func performNetworkCall() {
        let restURL = self.url
        print("Performing URL call to \(restURL) with timeout \(self.timeout)")
    }
}

```

And an implementation : 
```swift
class MyRestServiceClient : RESTClient {
    override var url : String {
        return "http://www.foo.com/client"
    }
    
}
```

As you can see, url properties must be implemented by inherited class and should not be 
implemented by ancestor.
As workaround, we have added assertion, but this error is only detected at runtime and not 
at compile time and might create crash for end-user.

## Proposed solution
We propose to add a new keyword to indicate that a method or a property is abstract and 
not implemented in current class.
This indicates that method or properties must be implemented in inherited class that can 
be implemented.
We propose the keyword abstract that must be added to class and property/method : 

```swift
abstract class RESTClient {    
     var timeout = 3000

    abstract var url : String { get }
    
    func performNetworkCall() {
        let restURL = self.url
        print("Performing URL call to \(restURL) with timeout \(self.timeout)")
    }
}
```

And an implementation : 
```swift
class MyRestServiceClient : RESTClient {
    override var url : String {
        return "http://www.foo.com/client"
    }
    
}
```

## Detailed design
An abstract class cannot be instanciated. 

If a class contains one or more abstract methods/properties, it must be declared abstract.

A class that inherits from abstract must be declared abstract if it does not implements 
all inherited methods/properties.

If you try to implement an abstract class or a inherited class that implements partially 
abstract methods/properties, you will get a compiler error.

As for override keyword, abstract properties apply on setter, getter and observers. 

When declaring an abstract property, you must specify which methods must be implemented : 
get, set, didSet, willSet. 

If you do not specify anything, only setter and getter are made 
abstracts as below : 

```swift
    abstract var url : String
```

Observers provides default empty implementation.

Type is mandatory for abstract properties since it cannot be inferred.

## Impact on existing code
This change has no impact on existing code, but might change the ABI that is being 
stabilizing in Swift 3.0.

## Alternatives considered
As first reading, it seems that protocols and protocol extensions might fit the need. It 
actually does not because abstract classes can have attributs and properties that 
protocols does not support.

An alternative solution would be to add attributes to protocols and protocol extensions, 
but this might break compatibility with Objective-C runtime.



-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4233 bytes
Desc: not available
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160107/eb4cd2a7/attachment.p7s>


More information about the swift-evolution mailing list