1

So I know a class can only inherit a single class but can inherit multiple protocols. I am looking at some code here and confused as to why swift is throwing me an error.

protocol PaymentViewModelConfigurable: ViewModelWithResult {
    
}

class ViewModelWithResult {
    func printWithResultClass() {
        print("In View Model with result class")
    }
}

class PaymentViewModel: PaymentViewModelConfigurable {
    
    
}


class MainOne {
    let viewModel: PaymentViewModelConfigurable = PaymentViewModel()
}

So I would assume this is ok because my PaymentViewModel class inherits a protocol and that protocol inherits from a class.

But if I change the logic to this on my ViewModel to inherit the protocol & the class, its fine

protocol PaymentViewModelConfigurable: ViewModelWithResult {
    func payments()
}

class ViewModelWithResult {
    func printWithResultClass() {
        print("In View Model with result class")
    }
}

class PaymentViewModel: ViewModelWithResult, PaymentViewModelConfigurable {
    func payments() {
        print("Payments")
    }
}


class MainOne {
    let viewModel: PaymentViewModelConfigurable = PaymentViewModel()
    
    init() {
        viewModel.payments()
    }
}

These are the errors that come up:

'PaymentViewModelConfigurable' requires that 'PaymentViewModel' inherit from 'ViewModelWithResult'

Type 'PaymentViewModel' does not conform to protocol 'PaymentViewModelConfigurable'

HangarRash
  • 7,314
  • 5
  • 5
  • 32
Simon McNeil
  • 293
  • 1
  • 13

1 Answers1

2

So I know a class can only inherit a single class but can inherit multiple protocols.

Not quite. A class can conform to multiple protocols. It might seem like a pedantic correction of wording, but it's actually core to the issue here. The conformance and inheritance features are related and interconnected, but distinct. Similarly:

and that protocol inherits from a class.

It doesn't.

Everything after the : on a declaration of a protocol is not a list of superclasses and protocol conformances, like with classes. It's a list of requirements of that protocol. So this declaration:

protocol PaymentViewModelConfigurable: ViewModelWithResult {
    func payments()
}

Is saying: "PaymentViewModelConfigurable is a protocol that can be conformed to anything that's a subtype of ViewModelWithResult and has a func payments() method. It's as if you had written:

protocol PaymentViewModelConfigurable where Self: ViewModelWithResult {
    func payments()
}

The error messages spell this out quite explicitly:

Untitled 4.swift:11:7: error: 'PaymentViewModelConfigurable' requires that 'PaymentViewModel' inherit from 'ViewModelWithResult'
class PaymentViewModel: PaymentViewModelConfigurable {
      ^
Untitled 4.swift:11:7: note: requirement specified as 'Self' : 'ViewModelWithResult' [with Self = PaymentViewModel]
class PaymentViewModel: PaymentViewModelConfigurable {
      ^
Alexander
  • 59,041
  • 12
  • 98
  • 151