2016-11-24 52 views
0

这是我的代码:迅速沮丧的问题继承

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 
    } 
} 

如果我通过功能updateStudent一个Student对象,中投以MasterStudent导致崩溃。我想将Student对象变成MasterStudent对象。

感谢

+0

只要切断那条线。这条线是没有意义的(一个单独的演员什么也不做),并且你无论如何都没有理由演员。 – matt

+0

我认为你滥用基本的OOP编程。 MasterStudent从Student继承,所以你的**被强制downcast **可能导致崩溃。简单地说,你不能总是从学生向MasterStudent低调。 – dfd

回答

2

的代码将无法正常编译,对我来说,让我在IBM斯威夫特沙盒here做了一些小的调整和更新,它斯威夫特3。

我还添加了一些示例代码表明实例化一个MasterStudent对象,它是向上转型到Student,然后向下转换到一个MasterStudent当代码不会失败。但是,实例化一个Student对象时,将向下转换为MasterStudent时会失败。它不是正确的类型。想想这样,我简化了一点 - Student实例缺少degree属性,它需要与MasterStudent的行为相匹配。

as!操作员只有在确定downcast会成功时才能使用。这里就是这样一个例子:

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

当使用as!操作,编译器相信你的判断,并不会提供一个编译时错误。如果downcast不成功,您的用户将收到运行时异常,这通常是要避免的。 as?运营商是更安全的选择,因为如果不成功,它将向下或返回nil

+0

首先感谢您的快速回答,我看到您在沙箱中写的内容,并且当您使用更新功能发送MasterStudent对象而不是Student对象时,我需要的是发送一个学生并将其转换为MasterStudent,以便从该阵列的前一名学生,需要添加一个MasterStudent与所有额外的领域再次感谢 – user7024226

+0

我从你的私人评论理解,学生不能转换为MasterStudent,我该怎么做才能更新学生MasterStudent即使外地学位缺乏 – user7024226

+0

我创建了另一个沙盒快照[这里](http://swift.sandbox.bluemix.net/#/repl/5836feca27a1b233cd0fa980),它创建了一个新的MasterStudent对象而不是向下转换。请注意,如果未传入“度量”参数,则MasterStudent初始化程序现在具有默认度数值“Masters”。 –

1

你只能垂头丧气stMasterStudent如果它st对象已经是MasterStudent一个实例。否则,你将需要创建一个新的MasterStudent对象:

MasterStudent(name: st.name, degree: "...")