Some options:
Super/Sub class pattern (inheritance) where you use downcast to check if it is a Student or a Teacher.
Protocols work the same as the Super/Sub pattern but a type can conform to many protocols but can only inherit from one super.
if both Student and Teacher have the same properties you can also just add a property (a bool or an enum) to determine which is which.
create an enum instead of a protocol or super class that has a rawValue of User and has cases for both Teacher and Student. (this is complicated)
Use an enum with associated values.
Every method has it's own benefits and drawbacks.
If you want to be able to pass a User object to different functions in your app, you want to have some conformance/inheritance.
If you have some conformance/inheritance, you can load the user with a method of your choosing and then downcast as such:
if let student = user as? Student {
// do student stuffs
} else if let teacher = user as? Teacher {
// do teacher stuffs
}
Option 1, regular inheritance :
class User {
var username: String?
}
class Student : User {
// student properties
var year: Int?
}
class Teacher : User {
// teacher properties
var department: String?
}
Option 2, conform to instead of inherit from, AKA Protcols :
protocol User : class {
var username: String? { get set }
}
class Student : User {
var username: String?
// student properties
var year: Int?
}
class Teacher : User {
var username: String?
// teacher properties
var department: String?
}
Option 3, UserType property:
enum UserType {
case Student
case Teacher
}
class User {
var username: String?
// student properties, if it is a teacher we leave this blank
var year: Int?
// teacher properties,, if it is a student we leave this blank
var department: String?
var type : UserType?
}
Option 4, enum with User as rawValue:
class User: Equatable,StringLiteralConvertible {
var username: String?
// student properties
var year: Int?
// teacher properties
var department: String?
var type : String?
init(withType type:String) {
self.type = type
}
required convenience init(stringLiteral value: String) {
self.init(withType: value)
}
required convenience init(extendedGraphemeClusterLiteral value: String) {
self.init(withType: value)
}
required convenience init(unicodeScalarLiteral value: String) {
self.init(withType: value)
}
}
func ==(lhs:User,rhs:User) -> Bool {
if lhs.username == rhs.username && lhs.department == rhs.department && lhs.year == rhs.year && lhs.type == rhs.type {
return true
} else {
return false
}
}
enum UserType : User {
case Student = "Student"
case Teacher = "Teacher"
}
let user = UserType.Teacher
Option 5, enum with associated values:
class User {
var username: String?
}
class Student {
// student properties
var year: Int?
}
class Teacher {
// teacher properties
var department: String?
}
enum UserType {
case student(Student)
case teacher(Teacher)
}
UIApplication.sharedApplication().delegate as! AppDelegatein your application but pass the reference to your value to the view controllers, starting from AppDelegate. Hint 2: Use the Factory Pattern - just google it. You can instantiate an instance of any of these classes via a static method of the superclass for example. Then you can access the username any time. Checking if someone is a Student:myVariable is Student. Accessing a variable of a student:(myVariable as? Student)?.yearreturns the year as optional (nil when it isn't a student, the value otherwise)