What you are looking for is an abstract class. The purpose of an abstract class is to behave as a base class for concrete classes to inherit from, but an abstract class cannot be instantiated directly.
If Employee was an an abstract class then any attempt to actually instantiate an instance of Employee would be reported as an error by the compiler. You would need to instantiate a concrete subclass of Employee, such as SalariedEmployee or HourlyEmployee.
The definition of the Employee class would include that the calculatePay method was required and again a compile time error would occur if a concrete subclass did not implement that method.
Now, the bad news. Neither Objective-C nor Swift supports abstract classes.
You can provide a similar kind of class by providing an implementation of a method that throws an exception if it isn't overridden by a subclass. This gives a runtime error rather than a compile time error.
e.g.
class Employee { var givenName: String var surname: String ... init(givenName: String, surname: String) { self.givenName = givenName self.surname = surname } func calculatePay() -> Float { fatalError("Subclasses must override calculatePay") } } class SalariedEmployee: Employee { var salary: Float init(givenName: String, surname: String, annualSalary: Float) { salary = annualSalary super.init(givenName: givenName, surname: surname) } override func calculatePay() -> Float { return salary/12 // Note: No call to super.calculatePay } }
Whether the calculatePay is part of the base class or assigned to the base class through an extension that adds conformance to a protocol, the result is the same;
- The
Employee class will need a default implementation of the function that generates some sort of error - Failure of a subclass to implement the method will not cause a compile time error
You could assign a protocol, say, Payable to each subclass individually, but then as the protocol was not part of the base class, you couldn't say something like:
var employees[Employee] for e in employees { let pay = e.calculatePay() }
You would have to use the slightly more complicated:
for e in employees { if e is Payable { let pay = e.calculatePay() } }