Why I Can Not Inherit from Multiple Classes in Swift Just Like It's Library Classes

Why I can not inherit from multiple classes in swift just like it's library classes

Swift does not support multiple inheritance, following Objective C in this. This is NOT inheritance from two classes:

class SecondViewController: UIViewController, UITextFieldDelegate

It is inheritance from one class UIViewController and adopting the UITextFieldDelegate protocol. Read about protocols at https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Protocols.html

How to do multi-inheritance in swift?

As stated in the comments by @Paulw11 is correct. Here is an example that involves A & B inheriting from C. Which I have named DogViewController and CatViewController (which inherits form PetViewController). You can see how a protocol might be useful. This is just an ultra basic example.

protocol Motion {
func move()
}

extension Motion where Self: PetViewController {

func move() {
//Open mouth
}

}

class PetViewController: UIViewController, Motion{
var isLoud: Bool?

func speak(){
//Open Mouth
}
}

class DogViewController:PetViewController {

func bark() {

self.speak()

//Make Bark Sound
}
}

class CatViewController: PetViewController {

func meow() {

self.speak()

//Make Meow Sound


}

}

//....

let cat = CatViewController()
cat.move()
cat.isLoud = false
cat.meow()

multiple inheritance from classes

In swift your class can inherit just from single class.
You can have a look on protocol and protocol oriented programming.
The other solution is:

// Class A inherits from UIViewController
class A: UIViewController
// Class B inherits from A and also from UIViewController
class B: A

In your example you said that your main class inherits from BaseViewController which inherits from UIViewController so if you want to create another class which inherits from BaseViewController and UIViewController you just need to do:

class A: BaseViewController

that's make it inherit from UIViewController too.

How to derive one class from two different classes in Swift based on API level?

Unfortunately (or fortunately depending on how you look at it), exactly what you're trying to do is not possible with Swift or Objective-C from a language perspective. The @available attribute you're using is to tell the compiler that this class is only available if you're compiling a target with a deployment target greater than what you specified.

@MartinR made mention of the #available and the general pattern that you should employ to achieve your goal.

The reason these 2 things are available and necessary to support backward compatibility is because compiled code doesn't necessarily have all of the information about the runtime. The compiler/linker check for the existence of APIs, classes, etc by using the headers and module maps of the SDK at compile time. But, your app is linked with the system frameworks dynamically at runtime. This pattern is why your app doesn't have to be distributed with copies of every part of the SDK that it uses.

In your case, you have SDK9 and are trying to support a runtime of iOS 8 or less. The SwipeTableViewCell doesn't work in iOS 8 likely because it uses APIs that are only available in iOS 9. All of this doesn't prevent SwipeTableViewCell from existing on iOS 8 devices, it just prevents it from working.

You really should evaluate whether you need to support iOS 8 at all. If you change your target's deployment target to iOS 9 and release it to the App Store, people running iOS 8 won't get the update or be able to install it.

Update

After doing some thinking, and some research, I came up with a possible solution for your situation. I only tested it in an environment that relies on a storyboard for the UI, but I think it can gracefully bridge your iOS targets.

import UIKit

class ViewController: UITableViewController {

@IBOutlet var staticCell: Any? // In the storyboard, tell the cell to by a "MySwipeableCell"

override func viewDidLoad() {
super.viewDidLoad()

if staticCell is SwipeTableViewCell {
print("This class was converted magically, which means we're on iOS 9 or later")
}
}
}

class SwipeTableViewCell: UITableViewCell {
// Standin for your library class
}

class MySwipeableCell: UITableViewCell {

override func awakeAfter(using aDecoder: NSCoder) -> Any? {
if #available(iOS 9, *) {
// This will replace the MySwipeableCell with an instance of SwipeTableViewCell instead
return SwipeTableViewCell.init(coder: aDecoder)
}

return self
}
}

Inheriting Multiple Classes in F#

UICollectionViewDelegate and UICollectionViewDataSource are not classes, but protocols, which are like interfaces in F#

So your could should look something like this (abstract code):

[<Register ("LandlordHome")>]
type LandlordHome (handle:IntPtr) =
inherit UIViewController (handle)
interface UICollectionViewDelegate with
// implementation of UICollectionViewDelegate
interface UICollectionViewDataSource with
// implementation of UICollectionViewDataSource

Cannot inherit from non-open class swift

Found the answer myself.

In Swift 3 you can now mark a class as open instead of public this allows files outside of the module to subclass that class.

Simply replace public in your module class with open.

Reference here.



Related Topics



Leave a reply



Submit