Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 将超类转换为其子类之一_Swift_Xcode_Casting - Fatal编程技术网

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代码的问题。