user7024226 user7024226 - 14 days ago 7
Swift Question

swift downcast issue from superclass to subclass

This is my code:

class Student {
var name: String?
init (name: String) {
self.name = name
}
}

class MasterStudent: Student {
var degree: String?
init(name: String, degree: String) {
self.degree = degree
super.init(name: name, degree: degree)
}
}

fun updateStudent(stu: Student) {
var count = 0
for st in studentArray {
if (st.id == stu.id) {
studentArray.removeAtIndex(count)
st as! MasterStudent //thread 1 signal :SIGABRT
studentArray.append(stu)
}
count += 1
}
}


If I pass the function
updateStudent
a
Student
object, the cast to
MasterStudent
results in a crash. I want to turn the
Student
object into a
MasterStudent
object.

thanks

Answer

The code would not compile as-is for me, so I made some small adjustments and updated it to Swift 3 in the IBM Swift Sandbox here.

I also added some example code demonstrating that the code does not fail when instantiating a MasterStudent object that is upcast to a Student and then downcast to a MasterStudent. However, instantiating a Student object will fail when it is downcast to a MasterStudent. It is not of the right type. Think of it this way, and I'm simplifying a bit -- a Student instance is missing the degree property that is required to match the behavior of a MasterStudent.

The as! operator should only be used when it is certain that the downcast will succeed. Here is one such example:

let obj:Any = "Hello World"
let obj2 = obj as! String

When using the as! operator, the compiler is trusting your judgment and will not provide a compile-time error. If the downcast is unsuccessful, your users will receive a run-time exception, which is generally to be avoided. The as? operator is a safer choice, as it will either downcast or return nil if unsuccessful.