Syntax for method hiding - swift

What is the syntax for method hiding in swift? I've tried a bunch of options in the playground, but keep getting errors. Haven't been able to find any documentation on it either.
In superclass:
func performFunction() {
print("performing function...")
}
In subclass, tried a couple different options that do not seem to work
new func performFunction() {
print("function...")
}
and
func new performFunction() {
print("function...")
}

You're looking for the override keyword:
class SubClass: ParentClass {
override func performFunction() {
println("function...")
}
}
See the Swift Programming Language: Inheritance for more info.

Question answered thanks to Nate Cook!
"Method hiding isn't possible in Swift, only overriding. Moreover, class methods (as implemented using the static keyword) are all final, so you can't even override at that level."

Related

Is there an equivalent to NS_REQUIRES_SUPER in Swift? [duplicate]

Is there a Swift equivalent to
__attribute((objc_requires_super))
which gives a warning if a method doesn't call it's super method?
Basically, I want to warn (or even better, throw a compiler error) if an overridden method doesn't call its super method.
No, there is no Swift equivalent to __attribute((objc_requires_super)).
The equivalent feature, Swift Attributes, contains no such attribute.
The section of the Swift inheritance documentation where such a feature would be mentioned says only:
When you provide a method, property, or subscript override for a subclass, it is sometimes useful to use the existing superclass implementation as part of your override.
Note that you can prevent overriding functions using final, so you could effectively accomplish what you want by providing empty overridable methods that are called by non-overridable methods:
class AbstractStarship {
var tractorBeamOn = false
final func enableTractorBeam() {
tractorBeamOn = true
println("tractor beam successfully enabled")
tractorBeamDidEnable()
}
func tractorBeamDidEnable() {
// Empty default implementation
}
}
class FancyStarship : AbstractStarship {
var enableDiscoBall = false
override func tractorBeamDidEnable() {
super.tractorBeamDidEnable() // this line is irrelevant
enableDiscoBall = true
}
}
Subclasses would then override the overridable methods, and it wouldn't matter whether they called super or not since the superclass's implementation is empty.
As Bryan Chen notes in the comments, this breaks down if the subclass is subclassed.
I make no claims to whether this approach is stylistically good, but it is certainly possible.

Difference when declaring swift protocol using inheritance from another protocol or using where Self

I still don't understand what is the difference when declaring a Swift protocol using inheritance:
protocol SubProtocol: SuperProtocol { ... }
or using where Self
protocol SubProtocol where Self: SuperProtocol { ... }
By doing this on these two ways the results are exactly the same, both options compile fine, and it works, SubProtocol will have the same stuff than SuperProtocol has. So what is the difference?
The only difference I can see is the semantic, one is more clear than the other (see example below). But this is my point of view and I would like to know if someone else thinks the same, or perhaps I am miss-understanding the whole thing.
Example:
protocol Progressable {
var isInProgress: Bool { get }
}
protocol Downloadable: Progressable {
func download()
}
protocol ProgressReporting where Self: Progressable {
func reportProgress() -> Bool
}
For me, Downloadable makes sense it inherits from Progressable, every download is progressable, so that is fine.
But ProgressReporting not necessary needs to inherit from Progressable, for me it would make more sense to constraint it by using where, this way the reader can know that whoever implements it, will need to conform to Progressable too (see the comments on the code below), here is when I think the semantic is different.
class MyClassA: Downloadable {
var isInProgress: Bool { return true }
func download() {}
func foo() {
/*
I have access to `self.isInProgress` because this class conforms `Downloadable`
which inherits from `Progressable`, so this makes sense
*/
_ = self.isInProgress
}
}
class MyClassB: ProgressReporting {
var isInProgress: Bool { return true }
func reportProgress() {}
func foo() {
/*
I have access to `self.isInProgress` but according to `ProgressReporting` definition,
this class should be `Progressable` which is not, at least not explicitely
*/
_ = self.isInProgress
}
}
I would apreciate if someone can explain me what are the differences 🙂
Thanks in advance.
Speaking about Swift5, there is no difference between the two forms, see Swift 5 Release notes:
Protocols can now constrain their conforming types to those that subclass a given class. Two equivalent forms are supported:
protocol MyView: UIView { /*...*/ }
protocol MyView where Self: UIView { /*...*/ }
Swift 4.2 accepted the second form, but it wasn’t fully implemented and could sometimes crash at compile time or runtime. (SR-5581) (38077232)

Can I override a Swift method that has been overridden by an extension?

I'm trying to create an extension for debugging a class to print some output when you enter certain methods. I want to be able to reuse this code in many different classes, and I want to keep those classes clean from this debugging code while also not repeating code (keeping DRY). That's why I thought of using an extension like this:
class A: ... {
override func myMethod() {
super.myMethod()
print("hello A")
}
}
extension A {
override func myMethod() {
print("hello extension")
}
}
And I would like that when myMethod() is called, to see this
hello extension
hello A
(or the other way around, I don't care)
But the problem is that the compiler is saying "myMethod() has already been overridden here"
Any ideas?
Extensions can add new functionality to a type, but they cannot
override existing functionality.
Answer is here Swift override function in extension

Can a Swift class be extended multiple times with the same methods?

I am designing a framework that uses protocols and extensions to allow for third-parties to add support for my framework to their existing classes.
I'd also like to include some built-in extensions for known classes like UIView, but I don't want to prevent users from defining their own additional support for the same classes.
My question is is there any way that I can extend the same class twice, and override the same (protocol) method in that class both times, while still having some way to call the other if the first one fails.
Elaboration: I really have three goals here I want to achieve:
I want to allow users of my framework to provide their own extensions for their own (or any) UIView subclasses.
I also need some way to allow general behavior that can apply to all UIViews as a fallback option (i.e. if the specific class extension can't handle it, fall back on the generic UIView extension).
I'd also like to separate out my own implementation, by providing some built-in generic view handling, but in such a way that it doesn't prevent third parties from also defining their own additional generic handling. (If I can't do this, it's not a big deal, the first two parts are the most important.)
I have part 1 working already. The problem is how to get this fallback behavior implemented. If I do it all with extensions, the subclass will override the superclass's implementation of the protocol method. It could call super.method, but I'd like to avoid putting that responsibility on the subclass (in case the author forgets to call super).
I'd like to do this all from the framework code: first, call the object's protocol method. If it returns false, I'd like to somehow call the generic UIView handler.
Now that I'm typing it all out, I'm wondering if I can just use a different method for the generic fallback and be done with it. I just figured it would be elegant if I could do it all with one method.
No! It can't be extended multiple times.
extension Int {
var add: Int {return self + 100} // Line A
}
extension Int {
var add: Int {return self + 105} //Line B
}
Doing so would create a compile time error ( on Line B) indicating: Invalid redeclaration of 'add'
Swift is a static typing language and helps you find these sorts of errors before runtime
In Objective-C you can write this and still not get an error, however the result would be undefined, because you wouldn't know which method gets loaded first during runtime.
Overriding a single protocol method twice in 2 separate extensions wouldn't work, because the protocol method names would collide. Once compiled, they're all just methods on the same class. With that in mind, perhaps put all the protocol methods in their own extension & call them from within the other ones?
The following could be one general option. Could get messy if you decide to keep adding additional extension functionality.
class baseClass {
//stuff
}
extension baseClass: myProtocol {
override func myProtocolMethod(args) -> returnType {
//Repeat this in a separate extension & your method names collide
var status: Bool
//protocol method code sets status as appropriate...
return status = true ? optOne(status) : optTwo(status)
}
func optOne(status:Bool) -> returnType{
//do the 'true' thing
return returnType
}
func optTwo(status:Bool) -> returnType{
//do the 'false' thing
return returnType
}
}
extension baseClass {
var oneExtension = myProtocolMethod(someArg)
}
extension baseClass {
var twoExtension = myProtocolMethod(someArg)
}
I realize this Question is over a year old and the original poster has probably moved on to other things, but I'd like to share an idea anyways and perhaps get some feedback.
You say that you want a method that can be overwritten multiple times. The short answer, like many in this thread have given is no, but the long answer is yes.
We can solve the issue with a bit of generic magic.
class MyView: UIView {
var customizer: MyProtocol<MyView> = Defaults()
func willCallCustomizer() {
customizer.coolMethod(self)
}
}
// Use this class as if it were a protocol
class MyProtocol<T: UIView>: NSObject {
func coolMethod(_ view: T) {}
}
// Class inherits from the "protocol"
class Defaults: MyProtocol<MyView> {
override func coolMethod(_ view: MyView) {
// Some default behavior
}
}
/// on the clients end...
class CustomerCustomizer: MyProtocol<MyView> {
override func coolMethod(_ view: MyView) {
// customized behavior
}
}
So if the client wants to use their own customizer they can just set it, otherwise it will just use the default one.
myViewInstance.customizer = CustomerCustomizer()
The benefit of this approach is that the client can change the customizer object as many times as they want. Because MyProtocol is generic, it may be used for other UIView's as well; thus fulfilling the role of a protocol.

Swift Generics and Protocol Extensions

I have a protocol Reusablethat has a static function static func reuseId() -> String and a protocol extension that defines the default implementation for the function. Then, I implemented a extension on UITableViewCell to conform to the Reusable protocol. I can now use the function on my TableViewCells without a problem: SomeTableViewCell.reuseId().
The Problem I have is with Generics. I have a generic class that has a generic parameter of the type UITableViewCell:
internal class SomeClass<CellType: UITableViewCell>: NSObject {
...
}
I want to be able to use the function specified in Reusable in my generic class on CellType but unfortunately this does not work as expected. The compiler always generates the error Type 'CellType' has no member 'reuseId'.
Does anybody know why this is happening? Is there a workaround?
I am using Xcode 7.0 with Swift 2.0.
Greetings from Germany
UPDATE: Here is some sample code that better shows my problem:
import UIKit
protocol Reusable {
static func reuseId() -> String
}
extension Reusable {
static func reuseId() -> String {
return String(self).componentsSeparatedByString(".").last!
}
}
extension UITableViewCell: Reusable { }
class SomeGenericClass<CellType: UITableViewCell> {
func someFunction() {
let reuseIdentifier = CellType.reuseId()
}
}
This Code will generate the above error but I do not quite understand why this happens. I think the main difference to the sample code that jtbandes posted is that I use a static function.
UPDATE: The issue is fixed in Xcode 8.3 beta 2. The sample code above now works as expected (after migrating it to Swift 3 of course).
That's an interesting problem. Your code seems like it should work; you might want to file an enhancement request.
Here's a workaround that seems to work correctly:
class SomeGenericClass<CellType: Cell> {
func someFunction() {
let reuseIdentifier = (CellType.self as Reusable.Type).reuseId()
}
}
Another (workaround) way to get what you need:
class GenericExample<CellType:UITableViewCell where CellType:Reusable>
{
func test() -> String {
return CellType.reuseId()
}
}
GenericExample<UITableViewCell>().test() // returns "UITableViewCell"
GenericExample<MyCell>().test() // returns "MyCell"