Can I extend a final class in Swift? - swift

I'm using a third-party library for a new app that I'm making using Swift. The author of the class/library has made it final using the final keyword, probably to optimise and to prevent overriding its properties and methods.
Example:
final public class ExampleClass {
// Properties and Methods here
}
Is it possible for me extend the class and add some new properties and methods to it without overriding the defaults?
Like so:
extension ExampleClass {
// New Properties and Methods inside
}

An extension may not contain stored properties but you can add methods inside.

Extensions (like Objective-C categories) don't allow stored properties.
Methods and computed properties are fine though.
A common (but IMO hacky) workaround in Objective-C was to use associated objects to gain storage within categories. This also works in Swift if you import ObjectiveC.
This answer contains some details.

Yes, you can extend a final class.
That extension has to follow the usual rules for extensions, otherwise it's nothing special.

While you cannot create new stored properties in extensions you can add methods and computed properties.
Example computed property:
extension ExampleClass {
// computed properties do not have a setter, only get access
var asInt: Int? {
Int(aStringPropertyOnTheClass)
}
}

Related

How can a Swift module/class work around the lack of language support for "protected" members?

I'm faced with a situation where I am defining a reusable base class in a module, and I want to provide certain functions that should be callable only by subclasses, not external users of that subclass.
I'm writing a framework and packaging it as a Swift module. Part of my framework includes a base class that can be subclassed to add functionality, but whereby the derived class also has a further external purpose as well. Imagine defining a new kind of view: it derives from UIView or NSView, then provides additional logic, and is then itself instantiated by another party.
In this case, I'm the one defining the UIView-like class that is intended to be subclassed, and along with it comes a lot of private UIView internal stuff, like measurement, arranging, who knows, internal stuff.
The point is, end users of this new view class don't want to see the internals of the architecture that supported the subclassing, those should be completely inside the black box of what the subclass represents.
And it strikes me that this is now impossible in Swift.
I really don't understand why Swift got rid of protected access control. According to Apple, the function that I want to expose only to subclasses "isn't really useful outside the subclass, so protection isn’t critical".
Am I missing something? Is this a whole class of design patterns that Swift simply cannot support?
One thought that occurs to me is I could perhaps split up the public-public and the private-public parts of my class into two parts, perhaps using protocols, whereby public-public users would only see the public protocol and "private" public users would see the "private" protocol as well. Alas this seems like a lot of engineering for something that used to be free.
FWIW — I've been continually asking for better access control in Swift (including protected) since before there was access control in Swift. Now, 3.5 years after we were told to give the Swift approach to access control a try, Swift has been my primary language for almost 3 of those years and I still think the access control paradigm is clumsy and unable to model concepts that are easy in almost all similar languages.
The largest mitigating factor for me is that Swift has steered me away from ever using inheritance and subclassing 95% of the time, which I think is a good thing. So this issue comes up less than it may have otherwise. But for situations exactly as you are describing, there isn't an equivalent way to accomplish what you are doing using only protocols and protocol extensions, so you are stuck either polluting a public API with possibly harmful internal details, or using some workaround (like the one that follows) which has the smallest possible public API exposure, and simulates what you want at the cost of boilerplate and awkwardness.
That said, the approach I take is somewhat inspired by Objective C, where there is also no real protected access control, but the convention is to declare a public API header (which client code will import and reference) and a special "+Subclassing" header which only subclasses will import in their implementation, giving them visibility into the not-for-public-consumption internals.
In Swift, this isn't directly possible either, but given a class like this:
open class SomeClass {
private var foo: String
private var bar: Data
public init(){
foo = "foo"
bar = Data()
}
private func doInternalThing() {
print(foo)
}
}
You can add a nested "Protected" wrapper via extension (has to be in the same file as your class declaration), which takes an instance of the class (or a subclass) and exposes the protected-level internals as a sort of proxy:
// Create a nested "Protected" type, which can accept an instance of SomeClass (or one of its subclasses) and expose the internal / protected members on it
public extension SomeClass {
public class Protected {
unowned private var someClass: SomeClass
public var foo: String {
get {
return someClass.foo
}
set {
someClass.foo = newValue
}
}
public init(_ someClass: SomeClass) {
self.someClass = someClass
}
public func doInternalThing() {
someClass.doInternalThing()
}
}
}
Outside of the framework, in the client application, the protected members are accessed in a subclass like this:
class SomeSubclass: SomeClass {
private lazy var protected: SomeClass.Protected = { SomeClass.Protected(self) }()
func doSomething() {
protected.foo = "newFoo" // Accesses the protected property foo and sets a new value "newFoo"
protected.doInternalThing() // Prints "newFoo" by calling the protected method doInternalThing which prints the foo property.
}
}
There are pros and cons for this approach. The cons are mainly the amount of boilerplate you need to write to map all your properties and functions from the Protected wrapper to the actual class instance as shown above. Also, there is no avoiding the fact that consumers will see SomeClass.Protected as a publicly visible type, but hopefully it's clear that it shouldn't be used and it's difficult enough to use it arbitrarily that it won't happen.
The pros are that there isn't a lot of boilerplate or pain for clients when creating subclasses, and its easy to declare a lazy "protected" var to get the desired API. It's pretty unlikely that non-subclass would stumble upon or use this API accidentally or unwittingly, and it's mostly hidden as desired. Instances of SomeSubclass will not show any extra protected API in code completion or to outside code at all.
I encourage anyone else who thinks access control — or really in this case, API visibility and organization — to be easier than it is in Swift today to let the Swift team know via the Swift forums, Twitter, or bugs.swift.org.
You can kinda, sorta work around it by separating out the for-subclasses stuff into a separate protocol, like this:
class Widget {
protocol SubclassStuff {
func foo()
func bar()
func baz()
}
func makeSubclassStuff() -> SubclassStuff {
// provide some kind of defaults, or throw a fatalError if this is
// an abstract superclass
}
private lazy var subclassStuff: SubclassStuff = {
return self.makeSubclassStuff()
}()
}
Then you can at least group the stuff that's not to be called in one place, to avoid it polluting the public interface any more than absolutely necessary and getting called by accident.
You can also reconsider whether you really need the subclass pattern here, and consider using a protocol instead. Unfortunately, since protocols can't nest types yet, this involves giving the subclass-specific protocol an Objective-C-style prefixed name:
protocol WidgetConcreteTypeStuff {
...
}
protocol Widget {
var concreteTypeStuff: WidgetConcreteTypeStuff { get }
}

Extend a type using generics

In Swift, I am trying to create a generic class that can extend another class, while inheriting from it. I am able to do it in C++ as follows, but is there a way to do the same in Swift?
class Atom {};
template<typename Base, typename Extension>
class Extend: Base {
Extension _value;
};
int main() {
return 0;
}
One approach I have been trying to apply is Protocol Oriented Design, but it doesn't seem to be able to take a class and extend it. The best I reached is something like creating the extension manually, and declaring that it does extend Atom, but at that point, I would just create another class and add to it the respective property manually.
One way to do it is by generating the code for the subclass at compile or run time. check these answers of these questions:
How to generate code dynamically with annotations at build time in Java?, and Generating, compiling and using Java code at run time?.
You can add a custom generic method to the base class that would be overridden by each subclass (in the generated code) and it may return Object. It would be a working approach, if it's worth the hassle.

Different ways of making read public write private variables in swift?

I've completed a online course that taught us to write properties of classes as:
class bar {
private var _foo:Int
var foo {
return _foo
}
}
Since then i've seen
class bar {
private (set) var foo:Int
}
Is there any difference between these two ways of writing things, and which would be best practise?
The second option is simpler and clearer and it has the added benefit of still being able to add get, set, willSet, and didSet blocks on the property while still having clearly defined scope on the getter and setter. Of course you can still add those to the private property but I think the code starts to get less readable.
Also note that the first option is a public read-only computed property making use of a private stored property.
The second option can be either a computed or stored property.

Swift: class func .... why use this instead of func when creating a method inside a class?

I'm new to coding, apologies for dumb question.
Am following a tutorial to build a note taking app using Swift in Xcode.
Within a class definition I have been defining methods using the keyword func myMethod etc. At one point the instructor decides to define a Class method (within the existing class) using class func myMethod.
Why would you do this?
Thanks in advance for any feedback.
By defining a class method it means that you don't need an instance of that class to use the method. So instead of:
var myInstance: MyClass = MyClass()
myInstance.myMethod()
You can simply use:
MyClass.myMethod()
The static (class) function is callable without needing an instance of the class available; it may be called without having to instantiate an object.
This can be useful for encapsulation (avoiding placing the function in the global namespace), or for operations that apply to all objects of a given class, such as tracking the total number of objects currently instantiated.
Static functions can be used to define a namespaces collection of related utility functions:
aDate = Utils.getDate()
aTime = Utils.getTime()
Another common use is for the singleton pattern, where a static function is used to provide access to an object that is limited to being instantiate only once:
obj = MySingleton.getInstance()
obj.whatever()
One answer is namespacing. If a function is only relevant to a certain class there is no need to declare the function globally.
This is Swift's take on static methods:
Static methods are meant to be relevant to all the instances of a class (or no instances) rather than to any specific instance.
An example of these are the animation functions in UIView, or the canSendMail function from MFMailComposeViewController.

Visibility separation in Swift

Since swift doesn't use headers to specify it's interface, but access modifiers instead, I wondered if there is a good way to split public and private methods (perhaps in files, extensions or just visually). I'm thinking of the Java-esque way of declaring a FooInterface and FooImpl, but I don't really like the idea. Is there a nicer way to achieve this?
The bottom line is I want to be able to have all public members in one location and the private stuff in another - it just helps to avoid visibility mistakes.
I generally use the technique of declaring a private extension:
private extension MyClass {
}
I do that later in the file. However, that only works for methods. Properties still need to be declared in the main type definition.
You can just declare the methods as private:
private func doSomething() {
}