Swift 将超类转换为其子类之一
我有一个函数,它的类型为Swift 将超类转换为其子类之一,swift,xcode,casting,Swift,Xcode,Casting,我有一个函数,它的类型为Being。存在有两个子类:Person和Animal。我希望函数能够识别这两个类中的哪一个被传递,并对每个子类的特定属性进行处理 我认为这会奏效: func fight(attacker1: Being, attacker2: Being) -> String { if attacker1 is Person { let name1 = attacker1.name as! Person //Error: Value of type Bei
Being
。存在有两个子类:Person
和Animal
。我希望函数能够识别这两个类中的哪一个被传递,并对每个子类的特定属性进行处理
我认为这会奏效:
func fight(attacker1: Being, attacker2: Being) -> String {
if attacker1 is Person {
let name1 = attacker1.name as! Person //Error: Value of type Being has no member name
} else {
print("Its not a person")
}
但事实并非如此。要实现我想要的目标,最平滑/最短的方法是什么?您应该创建所需类型的新变量,并将参数放入该变量中
func fight(attacker1: Being, attacker2: Being) -> String {
if let att1 = attacker1 as? Person {
let name1 = att1.name
} else {
print("Its not a person")
}
这样,如果attacker1是Person,您只需将此值保存到att1常量中,以后可以将此常量用作Person类型的实例。因为Being是基类,所以它将无法访问任何子类属性。因此,首先,您必须检查attacker1和attacker2的类型。例如:如果attacker1的类型为Person,则可以将其类型强制转换为Person类型的实例,然后访问Person对象的属性。
注意:-确保先检查类型,然后对其进行类型转换,否则将崩溃 虽然@V.Khambir的代码有效,而且可能是更好的解决方案,但它没有指出您的代码存在的问题。您正试图将
.name
强制转换为人
.name
不是attacker1
的属性,这就是为什么会出现错误。您要做的是将attacker1
强制转换为Person
,然后访问name属性
func fight(attacker1: Being, attacker2: Being) -> String {
if attacker1 is Person {
let name1 = (attacker1 as! Person).name
} else {
print("Its not a person")
}
在这种情况下,为什么不在正在使用的基类中使用name呢?(因为动物和人都可以有名字)
attacker1.name as!人
这是错误的,看看@giorashc他们不能。不是名字就是物种。根据交给函数的类,它需要知道要问哪一个。因为这个答案更具体地回答了我的问题,所以我将其标记为正确。这不使用Swift最佳实践,因为你实际上要做两次铸造。。。检查一次,然后在需要访问name属性时再次检查。这里使用if-let语法的另一个答案实际上是您应该标记的答案,因为强制转换只执行一次,而且您有一个子类类型的强类型变量,因此不需要进一步强制转换。我完全同意您的看法!我也不喜欢我的代码示例,更喜欢V.Khambir的代码示例。这就是我写第一句的原因。然而,我想指出Marmelador代码的问题。