Swift has no abstract classes and methods. Instead, it offers protocols.
That's fine when your classes are either fully abstract or fully concrete.
But what is the best 'Swift' way to implement an abstract class that also has concrete methods?
Pseudo-code example:
class Animal {
abstract makeSound()
abstract eyeCount()
}
class Mammal : Animal {
override eyeCount { return 2 } // Let's assume all mammals have hard-coded 2 eyes...
class Cat : Mammal {
override makeSound { print "Meow!" }
}
class Dog : Mammal {
override makeSound { print "Woof!" }
}
In Mammal, I do want to implement the concrete method eyeCount()
because all mammals have 2 hard-coded eyes (supposedly) and I don't want to re-implement it in dog and cat. However, makeSound()
should only be implemented for Dog and Cat as mammals have varying voices.
How would you implement this in Swift? Thanks!
Abstract class can have both an abstract as well as concrete methods. A concrete class can only have concrete methods. Even a single abstract method makes the class abstract. Abstract class can not be instantiated using new keyword.
Abstract Classes Compared to Interfaces You cannot instantiate them, and they may contain a mix of methods declared with or without an implementation. However, with abstract classes, you can declare fields that are not static and final, and define public, protected, and private concrete methods.
Yes, this is allowed. A subclass can override a concrete method and declare it abstract. Of course, because this subclass contains an abstract method, the subclass itself must also be declared abstract. You would then need a further (concrete) subclass to implement the method to be able to instantiate an object.
Swift does not support abstraction like other language. Interface and abstraction both can achieve by Protocol. Abstraction is useful when you want to define method for common classes. For example if multiple classes is there, and they are using similar method.
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.
You can use Protocol Extensions to get the exact same behavior as with Abstract Classes: Checking if abstract methods are implemented in subclasses at compile time.
protocol Entity {
// MARK: - Abstract methods
func filename() -> String
// MARK: - Traits
func saveData(data: NSArray)
}
extension Entity {
func saveData(data: NSArray) {
// Do something and call:
let filename = filename()
}
}
Now you can implement the Entity
protocol on a Subclass and the compiler will force you to implement filename()
while the saveData()
method is already implemented.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With