# In a sub-class, is it possible to override a property of the super-class and constrain to a sub-type of the original property?

**URL:** <https://forums.swift.org/t/in-a-sub-class-is-it-possible-to-override-a-property-of-the-super-class-and-constrain-to-a-sub-type-of-the-original-property/10747>\
**Category:** Using Swift\
**Created:** [March 9, 2018, 9:41am UTC](https://forums.swift.org/t/in-a-sub-class-is-it-possible-to-override-a-property-of-the-super-class-and-constrain-to-a-sub-type-of-the-original-property/10747 "2018-03-09T09:41:21Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![tcldr](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tcldr/32/24405_2.png) [@tcldr](https://forums.swift.org/u/tcldr)\
**Post date:** [March 9, 2018, 9:41am UTC](https://forums.swift.org/t/in-a-sub-class-is-it-possible-to-override-a-property-of-the-super-class-and-constrain-to-a-sub-type-of-the-original-property/10747/1 "2018-03-09T09:41:21Z")

</div>

I'm struggling with the vocabulary to express this, but I'm extending some UIKit view classes for which I also need to extend the capabilities of the counterpart delegate protocol. Attempting to override the delegate property and specifying my own delegate as the type (which is a sub-type of the overridden property type) doesn't seem to be an option.

However, it must be possible somehow as Apple is using the mechanism in its own UIKit implementations. e.g. the `delegate` property on `UITableView` overrides(?) the `delegate` property on `UIScrollView` and constrains it to the `UITableViewDelegate` protocol which is a sub-type of `UIScrollViewDelegate`.

In pseudo-code:

```
protocol UIScrollViewDelegate { ... }
class UIScrollView {
    ...
    weak var delegate: UIScrollViewDelegate?
}

protocol UITableViewDelegate: UIScrollViewDelegate { ... }
class UITableView: UIScrollView {
    ...
    weak var delegate: UITableViewDelegate?
}

```

I can't seem to get this to work in my own code, so is this a restriction of swift that is somehow overlooked when dealing with obj-c code, or is there another way to do this?

---

<div class="post-metadata">

**Author:** ![Nevin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nevin/32/617_2.png) [@Nevin](https://forums.swift.org/u/Nevin)\
**Post date:** [March 9, 2018, 3:56pm UTC](https://forums.swift.org/t/in-a-sub-class-is-it-possible-to-override-a-property-of-the-super-class-and-constrain-to-a-sub-type-of-the-original-property/10747/2 "2018-03-09T15:56:33Z")

</div>

> [@tcldr](#):
>
> I’m struggling with the vocabulary to express this, but I’m extending some UIKit view classes for which I also need to extend the capabilities of the counterpart delegate protocol. Attempting to override the delegate property and specifying my own delegate as the type (which is a sub-type of the overridden property type) doesn’t seem to be an option.

I can help with the vocab part: you want covariant properties.

> [@tcldr](#):
>
> However, it must be possible somehow as Apple is using the mechanism in its own UIKit implementations. e.g. the `delegate` property on `UITableView` overrides(?) the `delegate` property on `UIScrollView` and constrains it to the `UITableViewDelegate` protocol which is a sub-type of `UIScrollViewDelegate`.

I don’t know how UIKit makes it work, but from a type-theory perspective it is unsound.

After all, since `UITableView` is a subclass of `UIScrollView`, you can store a `UITableView` instance in a variable of type `UIScrollView`. And then you can set the `delegate` of that variable to a `UIScrollViewDelegate` which is \*not\* a `UITableViewDelegate`.

See the problem?

---

<div class="post-metadata">

**Author:** ![tcldr](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tcldr/32/24405_2.png) [@tcldr](https://forums.swift.org/u/tcldr)\
**Post date:** [March 9, 2018, 4:17pm UTC](https://forums.swift.org/t/in-a-sub-class-is-it-possible-to-override-a-property-of-the-super-class-and-constrain-to-a-sub-type-of-the-original-property/10747/3 "2018-03-09T16:17:07Z")

</div>

Covariant properties, huh? Thanks for the vocab. Ah yes, that could be nasty.

I guess one solution in that situation would be something along the lines of the `super.delegate` returning a `UIScrollViewDelegate` and `self.delegate` only returning a `UITableViewDelegate` if indeed the delegate does conform – but I can see how that could become troublesome.

Thanks!

---

<div class="post-metadata">

**Author:** ![ole](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ole/32/18720_2.png) [@ole](https://forums.swift.org/u/ole)\
**Post date:** [March 13, 2018, 10:05pm UTC](https://forums.swift.org/t/in-a-sub-class-is-it-possible-to-override-a-property-of-the-super-class-and-constrain-to-a-sub-type-of-the-original-property/10747/4 "2018-03-13T22:05:50Z")

</div>

> I don’t know how UIKit makes it work, but from a type-theory perspective it is unsound.

I think in this particular case it would actually be (almost\*) sound because `UITableViewDelegate` has no required methods, only optional ones. So in a sense every `UIScrollViewDelegate` is a valid `UITableViewDelegate`.

\* “almost” because dynamic checks like `[delegate conformsToProtocol:@protocol(UITableViewDelegate)]` might not work as expected.

---

<div class="post-metadata">

**Author:** ![jrose](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jrose/32/408_2.png) [@jrose](https://forums.swift.org/u/jrose)\
**Post date:** [March 13, 2018, 10:23pm UTC](https://forums.swift.org/t/in-a-sub-class-is-it-possible-to-override-a-property-of-the-super-class-and-constrain-to-a-sub-type-of-the-original-property/10747/5 "2018-03-13T22:23:28Z")

</div>

I'm afraid you can't do this, because it violates the [Liskov substitution principle](https://en.wikipedia.org/wiki/Liskov_substitution_principle) and allows for unsafe code:

```swift
let table: UITableView = …
let scrollView: UIScrollView = table
scrollView.delegate = justAScrollViewDelegateNotATableViewDelegate
table.delegate?.tableView?(…) // ???

```

As Ole points out, the fact that UITableViewDelegate only has non-optional requirements makes this _nearly_ work in Objective-C, but it's still a generally unsafe pattern, and I wish UIKit didn't use it.

EDIT: Oops, I forgot to actually answer the question. We think it's better for Swift to model what Objective-C says it's doing than to enforce this strictly, but native Swift properties are still not allowed to do this, because Swift uses compile-time knowledge about types more than Objective-C does.

---

<div class="post-metadata">

**Author:** ![anthonylatsis](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/anthonylatsis/32/39232_2.png) [@anthonylatsis](https://forums.swift.org/u/anthonylatsis)\
**Post date:** [March 14, 2018, 1:58am UTC](https://forums.swift.org/t/in-a-sub-class-is-it-possible-to-override-a-property-of-the-super-class-and-constrain-to-a-sub-type-of-the-original-property/10747/6 "2018-03-14T01:58:54Z")

</div>

Nothing seems to prevent Swift from being able to follow the Liskov principle in this case. If a refinement protocol only adds optional requirements or only requirements with default implementations, that code can be made safe together with the `UIScrollView` - `UITableView` quite reasonable subtyping behavior in having a refined delegate. What is the reason for this being unsafe in the general case?

```swift
protocol A { func foo() }

protocol B: A { func soo() }

extension B { func soo() {} } // or @optional

class Foo: A { func foo() {} }

let a: A = Foo()

let b: B = a as! B // SIGABRT

```

> [@jrose](#):
>
> We think it’s better for Swift to model what Objective-C says it’s doing than to enforce this strictly

So, in other words, this is a very deep lying and complicated problem to solve?

---

<div class="post-metadata">

**Author:** ![jrose](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jrose/32/408_2.png) [@jrose](https://forums.swift.org/u/jrose)\
**Post date:** [March 14, 2018, 2:28am UTC](https://forums.swift.org/t/in-a-sub-class-is-it-possible-to-override-a-property-of-the-super-class-and-constrain-to-a-sub-type-of-the-original-property/10747/7 "2018-03-14T02:28:49Z")

</div>

In Objective-C conforming to a protocol gives you two things: you can send messages in the protocol to objects with that static (compile-time) implementing type without the compiler shouting at you, and you can check `-conformsToProtocol:`. As Ole pointed out, the violation I showed above breaks the latter use case, but not the former.

In Swift, conforming to a protocol means that there's a table of operations that you can invoke for the concrete type, which is either passed separately (generic functions), stored in the type (generic types), or stored next to the value (protocol values, the way most delegates are defined). That means that if you want to have a stronger type in a subclass, you need new storage, because the superclass doesn't have space for the new table. Additionally, if you actually _provide_ that new storage, you'd have to trap at runtime if someone tried to provide a type that _didn't_ conform to the protocol through the base class's interface (the way your example showed). That's implementable, but that does count as violating Liskov substitution, because something that's legal for normal UIScrollViews would cause a trap for UITableViews.

Now, people do make operations trap at runtime all the time, even when their superclass pretends to support it. But since there are other solutions to this problem that we think are better, it's not a feature we're interested in supporting.

```swift

class MyTableView1: MyScrollView {
  weak var tableDelegate: MyTableDelegate? {
    didSet { self.delegate = self.tableDelegate }
  }
}

class MyTableView2: MyScrollView {
  var tableDelegate: MyTableDelegate? {
    get { return super.delegate as! MyTableDelegate? }
    set { super.delegate = newValue }
  }

  override var delegate: MyScrollDelegate? {
    get { return super.delegate }
    set {
      precondition(newValue is MyTableDelegate?)
      super.delegate = newValue
    }
  }
}
```

---

<div class="post-metadata">

**Author:** ![tcldr](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tcldr/32/24405_2.png) [@tcldr](https://forums.swift.org/u/tcldr)\
**Post date:** [March 14, 2018, 10:12am UTC](https://forums.swift.org/t/in-a-sub-class-is-it-possible-to-override-a-property-of-the-super-class-and-constrain-to-a-sub-type-of-the-original-property/10747/8 "2018-03-14T10:12:48Z")

</div>

Interesting. So, if I understand correctly, the reason UIKit is able to do this is because in obj-c – even though it's potentially unsafe – the compiler doesn't object. Swift, being the safety conscious language that it is, does.

Therefore, we see some inconsistency between what is possible in a bridged obj-c type hierarchy and what is possible in a pure swift type hierarchy.

Makes sense.

I'm looking forward to seeing more of those pure swift frameworks.... :)

---

<div class="post-metadata">

**Author:** ![anthonylatsis](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/anthonylatsis/32/39232_2.png) [@anthonylatsis](https://forums.swift.org/u/anthonylatsis)\
**Post date:** [March 14, 2018, 1:57pm UTC](https://forums.swift.org/t/in-a-sub-class-is-it-possible-to-override-a-property-of-the-super-class-and-constrain-to-a-sub-type-of-the-original-property/10747/9 "2018-03-14T13:57:18Z")

</div>

My apologies, in my example `B` is supposed to refine `A` (edited), but it makes no difference anyway.

Now I see, thank you. This becomes much more obvious if tried against inheritance:

```swift
class A {
    var view: UIView
}

class B: A {
    override var view: UIButton
}

let b = B()
let a: A = b
a.view = UIView()
b.view.(...) ??

```

It seems logical at first, but is actually very unsafe and indeed does violate Liskov substitution.

Moreover, it appears the optional attribute produces optional methods in the sense of (A -\> B)? . I wonder if this is done to compensate for breaking the rules by adding safety.
