Overriding getter in Swift Overriding getter in Swift swift swift

Overriding getter in Swift


This works for me:

public class MyBaseClass {    private var _name: String = "Hi"    public internal(set) var name: String {        get {            return self._name        }        set {            self._name = newValue        }    }}public class MyDerivedClass:MyBaseClass {    override public var name: String {        get {            return "Derived - \(super.name)"        }        set {            super._name = newValue        }    }}MyDerivedClass().name

EDIT

This code works for me in a playground, placing it in the Sources -> SupportCode.swift file

public class MyBaseClass {private var _name: String = "Hi"public internal(set) var name: String {    get {        return self._name    }    set {        self._name = newValue    }}public init() {}}public class MyDerivedClass:MyBaseClass {    override public var name: String {        get {            return "Derived - \(super.name)"        }        set {           // do nothing        }    }   public override init() {    }}

It's a bit of a bodge because I get the same warning as you that internal(set) cannot be placed before the overridden subclass variable. It may well be a bug. And also I'm cheating to make sure the setter of the derived class does nothing.

A more common use of internal(set) or private(set) is to have code like this, which is similar to that in the documentation:

public class MyBaseClass {    public private(set) var _name: String = "Hi"    public var name: String {        get {            return self._name        }        set {            self._name = newValue        }    }    public init() {    }}public class MyDerivedClass:MyBaseClass {    override public var name: String {        get {            return "Derived - \(super.name)"        }        set {           super._name = newValue        }    }   public override init() {    }}

Here the setter can be read directly with MyDerivedClass()._name but it cannot be altered, e.g. this MyDerivedClass()._name = "Fred" would raise an error but MyDerivedClass().name = "Fred" would be OK.


Problem 1

MyBaseClass does not compile because:

  1. it has a stored property (_name)
  2. this stored property is non optional so it cannot be nil
  3. there is no initializer to populate it

So first of all we need to add a proper initializer to MyBaseClass

public class MyBaseClass {    private var _name: String    public internal(set) var name: String {        get { return self._name }        set { self._name = newValue }    }    init(name : String){        _name = name    }}

Problem 2

Now we can declare MyDerivedClass that overrides the computed property:

  1. we need to use the magic keyword override
  2. we need to provide both the setter and the getter

Here's the code:

public class MyDerivedClass: MyBaseClass {    public override var name: String {        get { return "Derived - \(super.name)" }        set { super.name = newValue }    }}

Test

From my playground:

let somethingWithAName = MyDerivedClass(name: "default name")println(somethingWithAName.name) // > "Derived - default name"somethingWithAName.name = "another name"println(somethingWithAName.name) // > "Derived - another name"