Abstract functions in Swift Language
There no concept of abstract in Swift (like Objective-C) but you can do this :
class BaseClass {
func abstractFunction() {
preconditionFailure("This method must be overridden")
}
}
class SubClass : BaseClass {
override func abstractFunction() {
// Override
}
}
abstract class and abstract function in swift
Swift unfortunately doesn't support abstract classes and methods.
To achieve a similar effect, in Swift we use protocols (Interfaces in Java).
So an example of your class would be:
protocol Fetcher {
var items: [Item] { get set }
func fetch()
func parse()
}
The one thing you can do, is mark members of a class final
to prevent them from being overridden in their subclass.
If you want a default implementation of one of your functions, you extend your protocol:
extension Fetcher {
func fetch() {
//SOME CODE
parse()
//SOME CODE
}
}
In which you won't need to implement this in your target class.
So for example, using the above protocol:
class Foo: Fetcher {
var items = [Item]()
// No need for fetch method, since it's already implemented
func parse() {
// Do something
}
}
Note, that the above implementation doesn't contain the method fetch
since it's already implemented in the protocol extension.
Abstract classes in Swift Language
There are no abstract classes in Swift (just like Objective-C). Your best bet is going to be to use a Protocol, which is like a Java Interface.
With Swift 2.0, you can then add method implementations and calculated property implementations using protocol extensions. Your only restrictions are that you can't provide member variables or constants and there is no dynamic dispatch.
An example of this technique would be:
protocol Employee {
var annualSalary: Int {get}
}
extension Employee {
var biweeklySalary: Int {
return self.annualSalary / 26
}
func logSalary() {
print("$\(self.annualSalary) per year or $\(self.biweeklySalary) biweekly")
}
}
struct SoftwareEngineer: Employee {
var annualSalary: Int
func logSalary() {
print("overridden")
}
}
let sarah = SoftwareEngineer(annualSalary: 100000)
sarah.logSalary() // prints: overridden
(sarah as Employee).logSalary() // prints: $100000 per year or $3846 biweekly
Notice that this is providing "abstract class" like features even for structs, but classes can also implement the same protocol.
Also notice that every class or struct that implements the Employee protocol will have to declare the annualSalary property again.
Most importantly, notice that there is no dynamic dispatch. When logSalary
is called on the instance that is stored as a SoftwareEngineer
it calls the overridden version of the method. When logSalary
is called on the instance after it has been cast to an Employee
, it calls the original implementation (it doesn't not dynamically dispatch to the overridden version even though the instance is actually a Software Engineer
.
For more information, check great WWDC video about that feature: Building Better Apps with Value Types in Swift
Abstract methods in Swift?
As of today (April 7, 2016), the proposal to introduce abstract classes and methods to Swift (SE-0026) has been deferred.
Joe Groff posted the following in swift-evolution-announce on March 7, 2016:
The proposal has been deferred from Swift 3. Discussion centered around whether abstract classes fit in the direction of Swift as a "protocol-oriented" language. Beyond any religious dogmas, Swift intends to be a pragmatic language that lets users get work done. The fact of the matter today is that one of Swift's primary target platforms is the inheritance-heavy Cocoa framework, and that Swift 2's protocols fall short of abstract classes in several respects [...].
We'd like to revisit this feature once the core goals of Swift 3 have been addressed, so we can more accurately consider its value in the context of a more complete generics implementation, and so we can address the finer points of its design.
I encourage you to read the full email, but I think the conclusion is the same as what you came up with in your question: we're currently stuck with the Objective-C way of doing things (raising exceptions).
Swift - mixing abstract and concrete methods
I would implement it like this:
class AbstractAnimal
{
// Fully abstract method
func methodThatReturnsSomething() -> String {
fatalError("methodThatReturnsSomething() is abstract and must be overriden!");
}
func eyeCount() -> Int {
return 2;
}
}
fatalError
prevents Xcode from complaining that abstract method methodThatReturnsSomething()
doesn't actually return anything.
Abstract classes in Swift
I strongly suggest you redesign your model in Swift. Just like when translating spoken languages, the outcome can sound very awkward, programming languages, when translated, can look awkward too. If you still want to translate from Java, read on.
The really hard problem to solve here is that B
is generic. If B
wasn't generic, everything would work way better in Swift.
For now, you just have to use a class
and pretend it is a protocol:
class A {
func sayHello() {
print("Hello from A")
}
}
class B<R> : A {
func sayHi() {
print("Hi from B")
}
}
class C<M, R> : B<R> {
// this fatalError() thing is really ugly, but I can't think of any other workarounds
func get(r: R) -> [M] { fatalError() }
func sayGracias() {
print("Gracias from C")
}
}
class D : C<String, String> {
override func get(r: String) -> [String] {
return [r]
}
}
let d = D()
d.sayHello()
d.sayHi()
d.sayGracias()
print(d.get(r: "Hello"))
If B
were not generic (you are not using the generic argument anyway), then this can be done:
class A {
func sayHello() {
print("Hello from A")
}
}
class B : A {
func sayHi() {
print("Hi from B")
}
}
protocol C {
// associated types in Swift are kind of like generic parameters for protocols
associatedtype M
associatedtype R
func get(r: R) -> [M]
}
extension C {
func sayGracias() {
print("Gracias from C")
}
}
// You have to specify that D inherits from B as well since protocols can't inherit from classes
class D : B, C {
typealias M = String
typealias R = String
func get(r: String) -> [String] {
return [r]
}
}
let d = D()
d.sayHello()
d.sayHi()
d.sayGracias()
print(d.get(r: "Hello"))
Related Topics
Pdf417 Decode and Generate The Same Barcode Using Swift
Nsattributedstring Boundingrect Returns Wrong Height
Keep Getting an Error: "Uiimagepickercontroller Extension Discovery Failed with Error: (Null)"
Swift Nstimer Dynamically Changing Interval
How to Reinterpret_Cast in Swift
Swiftui Tabview with List Not Refreshing After Objected Deleted From/Added to Core Data
Using UIscrollview Correctly in Swiftui
When to Detach Firebase Listeners in Tableview Cell
How to Make Phone Calls in Swift
Changing Associated Value of Enum Swift
How to Get The Range of The First Line in a String
In App Purchase in Skscene Not Working
Mkpolyline Broken When Using Type Satelliteflyover