Reputation: 114
Best approach to make class design if we have two class as below:
class Teacher {
var name
var age
var TechId
}
class Student {
var name
var age
var StdID
}
I try it using that :
class Person {
var name
var age
}
class Student : Person {
var StdID
}
class Teacher : Person {
var TechID
}
But now problem is that student become teacher and vice versa.
Can you any one provided best solutions for that using Swift?
Upvotes: 2
Views: 103
Reputation: 437937
You said:
But now problem is that student become teacher and vice versa.
If you can change back and forth like this, I'd first suggest a concrete and distinct object to capture what precisely is transitioning from one to the other:
class Person {
var name: String
var age: Int
}
Note, in your example, you are considering this Person
to be what other languages consider to be an abstract/virtual class. But I'm suggesting that you want to make this a concrete object (the actual person) that you instantiate.
The question then becomes how you represent "student" and "teacher". One simple pattern is to consider it a question of membership in some relevant collection:
typealias StudentID = String
var students: [StudentID: Person]
typealias TeacherID = String
var teachers: [TeacherID: Person]
In that case, transitioning from a student to a teacher (or vice versa) is merely a question of adding/removing from the appropriate dictionaries.
The above is a bit constrained, though. For example, what if you wanted to keep track of more student-specific properties (e.g. enrollment date, etc.) or teacher-specific properties (e.g. hire date, social security number, annual salary, etc.). This suggests you might want specific types for these student and teacher types:
class Student {
let studentID: String
let person: Person
}
class Teacher {
let teacherID: String
let person: Person
}
And then your students and teachers collections become simple arrays:
var students: [Student]
var teachers: [Teacher]
But by making the Person
a property (rather than a base class), if you know which person is associated with a particular "student id", you can now associate that person with a particular "teacher id", too. But the idea is the same, it's merely a question of membership in the appropriate collection/type, not an issue of trying to change the inherent type of the person.
The alternative is a protocol oriented pattern:
protocol Person {
var name: String { get }
var age: Int { get }
}
struct Student: Person {
let studentID: String
var name: String
var age: Int
init(name: String, age: Int) {
studentID = UUID().uuidString
self.name = name
self.age = age
}
init(person: Person) {
self.init(name: person.name, age: person.age)
}
}
struct Teacher: Person {
let teacherID: String
var name: String
var age: Int
init(name: String, age: Int) {
teacherID = UUID().uuidString
self.name = name
self.age = age
}
init(person: Person) {
self.init(name: person.name, age: person.age)
}
}
This captures your notion that Person
is an abstract type that simply conforms to having certain properties. It avoids any ambiguity that Person
is not a type, itself, but merely a protocol to which types have to conform. You can only instantiate concrete Student
and Teacher
objects.
But then, if you want to create a Teacher
from a Student
, you can do:
let fred = Student(name: "Fred", age: 22)
let teacher = Teacher(person: fred)
Note, though, that this doesn’t “change” fred
into a Teacher
, but rather creates a new Teacher
whose Person
properties are copies of those of fred
.
Upvotes: 2
Reputation: 5275
For Swift, I would recommend something like this:
protocol Person {
var name: String { get }
var age: Int { get }
}
struct Teacher: Person {
let id: Int
let name: String
let age: Int
}
struct Student: Person {
let id: Int
let name: String
let age: Int
}
Use a Protocol to define the person. And use a Struct for Teacher and Student because once created you would not change their details as a Struct is immutable. Both Teacher and Student conform to Person protocol.
To test if a person is a Teacher or Student, you could do this:
func test(person: Person) {
switch person {
case is Teacher:
print("teacher")
case is Student:
print("student")
default:
preconditionFailure("Unknown person type")
}
}
Upvotes: 2