What are the implications of doing the following:
protocol A {
func f()
}
extension A {
final f() {}
}
I'm looking to understand what putting final in the extension over here does when compared to not putting it. I know what final does, I'm looking to understand overriding behaviour for classes implementing/not implementing f and their subclasses.
You can no longer mark extension funcs as final.
https://bugs.swift.org/browse/SR-1762
For Swift 2.0: Protocol Extensions
Methods, properties, or subscripts that you add to a class in an extension can also be marked as final within the extension’s definition.
Referring to this question of Inheritance, final keyword would not allow to override the (final) method defined in Extension, when it's Sub-classed.
For Swift 1.2:
This might be useful in context of Extensions Extensions can add new functionality to a type, but they cannot override existing functionality
Few things to look in context of Extensions, while decide on architecture of applications:
Protocol's cannot be extended to Extension.
It has go through a Class.
Existing functionality cannot be overridden (invalid redeclaration of)
On final keyword, this is my take it has no impact on Extensions methods as compared to classes(Inheritance). Please correct me if I'm wrong here.
Demo links:
Protocol A-->Class B-->Extension B
Protocol A-->Class B-->Extension B, then Class B --> Class C
Related
I've just learned about extensions and I was wondering, there was an example about extending a protocol. For example, let's say we have the protocol:
protocol CanFly {
func canFly()
}
which allows all the classes who can fly to basiclly to fly. Now lets say that we use extension to extend the protocol, and we do:
extension CanFly {
func canEat() {
print("I can eat")
}
}
What is the purpose of that if we can just add that func canEat to our protocol? More of those protocols are like an abstract struct so why would we add a func with a body to it?
just wanna say if I've made a mess im sorry for that lol, just want to clear out few things about extension <3
Per Swift documentation on Protocol Extensions:
Protocols can be extended to provide method, initializer, subscript,
and computed property implementations to conforming types. This allows
you to define behavior on protocols themselves, rather than in each
type’s individual conformance or in a global function.
This means you can run logic within the protocol extension function so you don't have to do it in each class that conforms to the protocol.
Personally, I also find extensions useful to extend the functionality of built-in classes like String or UIViewController since extensions can be called from anywhere in an app. I have some open-source extension snippets you can take a look at if you'd like.
Extending a protocol is just one of the possible use cases for extensions, really powerful and useful, but might be confusing at the start.
I suggest you looking through this article, as it dives deeper into more mundane, so to speak, ways to use it.
Kind of nerd question. It's unclear to me, what exactly makes this code works:
class Shape { }
extension Shape {
#objc func redraw() {
print("from ext")
}
}
class Circle: Shape { }
class Line: Shape {
override func redraw() { // Compiler error: Declarations from extensions cannot be overridden yet
print("from subclass")
}
}
let line = Line()
let shape:Shape = line
let circle = Circle()
line.redraw() //from subclass
circle.redraw() //from ext
shape.redraw() //from subclass
If I omit #objc keyword in extension, the code won't compile - it's expected behaviour since methods in extension use static method dispatch -> cannot be overridden.
But why adding #objc makes it work? According to documentation and most articles, all is #objc doing is making things visible to Objective-c runtime. To change method dispatch type there is a special keyword - dynamic. But seems it is not necessary here!
Help me figure out, why is adding #objc (and omitting dynamic) makes such things possible.
Extensions,
as the name already says, are supposed to extend/add/include methods
to an existing implementation, making them one of the most beautiful
things about Objective-C, and now Swift, since you can add code to a
class or framework you do not own. Therefore, it makes sense that
you’re not supposed to “replace” code in extensions, conceptually
speaking.
That’s why the compiler complains when you try to do it.
Also Check out this answer.
however this seems to be a support issue too, as swift compiler simply throw this error:
overriding non-#objc declarations from extensions is not supported.
According to Apple,
Extensions can add new functionality to a type, but they cannot
override existing functionality.
But that is not the case, as we are overriding from the extension not vice versa,
which takes us back to the declaration of extension.
Extensions add new functionality to an existing class, structure, enumeration, or protocol type. This includes the ability to extend types for which you do not have access to the original source code (known as retroactive modeling). Extensions are similar to categories in Objective-C. (Unlike Objective-C categories, Swift extensions do not have names.) Here.
Going back to the legacy topic swift compiler vs Objc compiler,
Dynamic dispatch vs. Static dispatch .
And there is no official documentation from apple on why this is not supported from the swift compiler or if they have any future plans to fix this or consider it an issue at all.
However, there’s no such thing as Swift dynamic dispatch; we only have
the Objective-C runtime’s dynamic dispatch. That means you can’t have
just dynamic and you must write #objc dynamic. So this is effectively
the same situation as before, just made explicit.
And here is a great article talking about this topic deeply.
This question already has answers here:
Swift extension example
(8 answers)
Closed 5 years ago.
As we have Object Oriented Programming, so we can make parent class which have all the functions those are needed for all child classes. so what is the purpose of extensions? I'm little bit confused in that question, please anyone help me.
Extensions
Adds functions to your class without subclassing, is very useful in cases where you don´t have the implementation of the class you are trying to extend, example classes that are inside an Framework or library
as is defined in https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Extensions.html
Extensions add new functionality to an existing class, structure,
enumeration, or protocol type. This includes the ability to extend
types for which you do not have access to the original source code
(known as retroactive modeling). Extensions are similar to categories
in Objective-C. (Unlike Objective-C categories, Swift extensions do
not have names.)
Extensions in Swift can:
Add computed instance properties and computed type properties Define
instance methods and type methods Provide new initializers Define
subscripts Define and use new nested types Make an existing type
conform to a protocol In Swift, you can even extend a protocol to
provide implementations of its requirements or add additional
functionality that conforming types can take advantage of. For more
details, see Protocol Extensions.
NOTE
Extensions can add new functionality to a type, but they cannot
override existing functionality.
Extension Syntax
Declare extensions with the extension keyword:
extension SomeType {
// new functionality to add to SomeType goes here
}
An extension can extend an existing type to make it adopt one or more protocols. To
add protocol conformance, you write the protocol names the same way as
you write them for a class or structure:
extension SomeType: SomeProtocol, AnotherProtocol {
// implementation of protocol requirements goes here
}
Adding protocol conformance in this way is described in Adding
Protocol Conformance with an Extension.
An extension can be used to extend an existing generic type, as
described in Extending a Generic Type. You can also extend a generic
type to conditionally add functionality, as described in Extensions
with a Generic Where Clause.
Hope this help to clarify you
It seems reasonable to use UML Interfaces to visualize Swift Protocols in UML. But how should I visualize an extension that provides a default implementation for a specific protocol? Should I just use a class like <<extension>>ProtocolName that inherits from that protocol?
An extension exists in the scope of a certain class and just adds some functionality to it. So I would represent the extension as subclass (eventually packaging might be preferred). To show that it's an extension I would use a stereotype. The dependency on the class which is extended is somewhat optional since in the context it is a naming convention.
If the extension will additionally adhere to some protocol you just add realization relations to the according interface classes.
This is one way to express this. Since there is no native UML construct for an extension you are relatively free to invent you own idiom here.
In short
A Swift protocol is in principle an UML interface: a class does not inherit anything from an interface/protocol, but must implement the feature that the interface/protocol promises.
Protocol extensions change this semantic equivalence: a protocol extension can provide features that the conformant classes would inherit. This is incompatible with an UML interface and corresponds to the semantic of an abstract class. But using abstract classes would make it confusing in regard to multiple inheritance. A stereotype «protocol» would seem preferable.
More explanations
Protocols
A swift protocol that is not extended corresponds indeed to an UML interface, despite slight differences in the wording:
Swift: A protocol defines a blueprint of methods, properties, and other requirements that suit a particular task or piece of functionality. The protocol can then be adopted by a class, structure, or enumeration to provide an actual implementation of those requirements.
vs:
UML: An Interface is a kind of Classifier that represents a declaration of a set of public Features and obligations that together constitute a coherent service. An Interface specifies a contract; any instance of a Classifier that realizes the Interface shall fulfill that contract.
Class extensions
There are different kind of extensions. A class extension adds features to the classes that they extend. If the extension occurs in the same file, it even has access to the private members of the class.
class MyClass {
func hello()->Void { print ("Hello, World !"); }
}
var c = MyClass()
extension MyClass { // first extension
func hellobye() -> Void { hello(); print(" Good bye!"); }
}
extension MyClass { // second extension
func bye() -> Void { print("Au revoir!"); }
}
c.hello() // the object has all the features of class + extension
c.hellobye() // even if it was defined befor the extension
c.bye()
The extension does not have a distinct name: it just redefines the original type, and the class behaves as if the initial definition and extensions would be the same classifier, just split up in the source code:
If the extensions and the initial class are defined in the same package, the cleanest way to represent it in UML would be to enrich the initial class, in the UML diagram.
If the extensions are defined in another package you could represent the full set of extensions to the same class as an own class, and a merge package to combine both. Since the original class is required for the extension to work you could in addition show a dependency between the two. Alternatively you could also think of an «class extension» stereotype. But again, grouping all the extensions to the same class in the package, because of the UML unique naming constraint.
Protocol extensions
Protocol extensions change the nature of the underlying protocol. While the original protocol was an interface without any implementation, the extended protocol will provide some implementations:
protocol MyProto {
var v1:String { get }
func op1() -> Void
func op2() -> Void
}
class Test : MyProto {
var v1:String = "abc"
func op1() -> Void { print("Op 1"); }
func op2() -> Void { print("Op 2"); }
}
extension MyProto {
var dev1:String { get { return "de"+v1; }}
func combo() -> Void { op1(); op2(); print("Combo 1 and 2"); }
}
var test = Test()
test.combo()
print (test.dev1);
In UML, the extended protocol would correspond to an «abstract» class, i.e a class that cannot be directly instantiated because of some missing features, but which may have some features well defined that are inherited. This situation is not fully supported in UML, since there is no modelling way to transform an interface into an abstract class:
The cleanest way would then be to use an UML profile that defines the stereotype «protocol» as a special form of «abstract» classes. The protocol extensions would then be dealt with as explained above for the classes, using a «protocol extension» in the situation where a «class extension» was mentioned.
With the addition of protocol extensions in Swift 2.0, it seems like protocols have basically become Java/C# abstract classes. The only difference that I can see is that abstract classes limit to single inheritance, whereas a Swift type can conform to any number of protocols.
Is this a correct understanding of protocols in Swift 2.0, or are there other differences?
There are several important differences...
Protocol extensions can work with value types as well as classes.
Value types are structs and enums. For example, you could extend IntegerArithmeticType to add an isPrime property to all integer types (UInt8, Int32, etc). Or you can combine protocol extensions with struct extensions to add the same functionality to multiple existing types — say, adding vector arithmetic support to both CGPoint and CGVector.
Java and C# don't really have user-creatable/extensible "plain old data" types at a language level, so there's not really an analogue here. Swift uses value types a lot — unlike ObjC, C#, and Java, in Swift even collections are copy-on-write value types. This helps to solve a lot of problems about mutability and thread-safety, so making your own value types instead of always using classes can help you write better code. (See Building Better Apps with Value Types in Swift from WWDC15.)
Protocol extensions can be constrained.
For example, you can have an extension that adds methods to CollectionType only when the collection's underlying element type meets some criteria. Here's one that finds the maximum element of a collection — on a collection of numbers or strings, this property shows up, but on a collection of, say, UIViews (which aren't Comparable), this property doesn't exist.
extension CollectionType where Self.Generator.Element: Comparable {
var max: Self.Generator.Element {
var best = self[self.startIndex]
for elt in self {
if elt > best {
best = elt
}
}
return best
}
}
(Hat tip: this example showed up on the excellent NSBlog just today.)
There's some more good examples of constrained protocol extensions in these WWDC15 talks (and probably more, too, but I'm not caught up on videos yet):
Protocol-Oriented Programming in Swift
Swift in Practice
Abstract classes—in whatever language, including ObjC or Swift where they're a coding convention rather than a language feature—work along class inheritance lines, so all subclasses inherit the abstract class functionality whether it makes sense or not.
Protocols can choose static or dynamic dispatch.
This one's more of a head-scratcher, but can be really powerful if used well. Here's a basic example (again from NSBlog):
protocol P {
func a()
}
extension P {
func a() { print("default implementation of A") }
func b() { print("default implementation of B") }
}
struct S: P {
func a() { print("specialized implementation of A") }
func b() { print("specialized implementation of B") }
}
let p: P = S()
p.a() // -> "specialized implementation of A"
p.b() // -> "default implementation of B"
As Apple notes in Protocol-Oriented Programming in Swift, you can use this to choose which functions should be override points that can be customized by clients that adopt a protocol, and which functions should always be standard functionality provided by the protocol.
A type can gain extension functionality from multiple protocols.
As you've noted already, protocol conformance is a form of multiple inheritance. If your type conforms to multiple protocols, and those protocols have extensions, your type gains the features of all extensions whose constraints it meets.
You might be aware of other languages that offer multiple inheritance for classes, where that opens an ugly can of worms because you don't know what can happen if you inherit from multiple classes that have the same members or functions. Swift 2 is a bit better in this regard:
Conflicts between protocol extensions are always resolved in favor of the most constrained extension. So, for example, a method on collections of views always wins over the same-named method on arbitrary collections (which in turn wins over the same-named methods on arbitrary sequences, because CollectionType is a subtype of SequenceType).
Calling an API that's otherwise conflicting is a compile error, not a runtime ambiguity.
Protocols (and extensions) can't create storage.
A protocol definition can require that types adopting the protocol must implement a property:
protocol Named {
var name: String { get } // or { get set } for readwrite
}
A type adopting the protocol can choose whether to implement that as a stored property or a computed property, but either way, the adopting type must declare its implementation the property.
An extension can implement a computed property, but an extension cannot add a stored property. This is true whether it's a protocol extension or an extension of a specific type (class, struct, or enum).
By contrast, a class can add stored properties to be used by a subclass. And while there are no language features in Swift to enforce that a superclass be abstract (that is, you can't make the compiler forbid instance creation), you can always create "abstract" superclasses informally if you want to make use of this ability.