Swift:如何检查子类上的基类和超类

Posted

技术标签:

【中文标题】Swift:如何检查子类上的基类和超类【英文标题】:Swift: How to check for base class and superclass on a subclass 【发布时间】:2017-02-11 11:57:31 【问题描述】:

为什么关注is检查为假?

class Person : BaseClass  ... 
class Parent : Person  ... 
.
.
let parent = Parent()
print("parent is BaseClass: \(parent.self is BaseClass)")
// this prints 'parent is BaseClass: false'

我如何检查子类的基类或超类?特别是如果我不知道对象的子类化程度有多深。

更新: 我的错误以下是正确的

print("parent is BaseClass: \(parent.self is BaseClass)")
// this prints 'parent is BaseClass: true'

但这个不是

class GenericClass<T: BaseClass>  
.
let myGeneric = GenericClass<Parent>()
print("myGeneric is GenericClass<BaseClass>: \(myGeneric.self is GenericClass<BaseClass>)")
// this prints 'myGeneric is GenericClass<BaseClass>: false'

在 Playground 中,我收到以下警告:

Playground.playground:从“GenericClass”转换为 不相关的类型“GenericClass”总是失败

那么如何检查与基类的泛型关系?

【问题讨论】:

这感觉像是对泛型的不恰当使用...您试图解决什么问题,让您认为您需要这样做? 这很简单。我需要对 GenericClass 及其所有子类做一些事情。在运行时,我不知道我可以管理的对象的类别。所以我需要检查它是否能够用它做正确的事情。但在我看来,Swift 无法检查泛型继承。在编译时也应该没问题。是什么让我想到扩展“is”运算符。 你能告诉我GenericClass&lt;BaseClass&gt;的子类吗?因为您的示例中没有任何内容。 对不起,我的意思是泛型类型的子类,例如 GenericClass 各种GenericClass 类型之间没有类层次结构。没有一个是其他任何一个的子类型。换句话说,GenericClass&lt;Parent&gt;不是GenericClass&lt;BaseClass&gt; 的子类。如果您将包含的类型公开为typealias,您也许 能够做到这一点... 稍微考虑一下这个想法,我也会这样做。 【参考方案1】:

您必须将包含的类型公开为类型别名。这是解决方案。

protocol BaseClass  
class Person : BaseClass  
class Parent : Person  

class GenericClass<T: BaseClass> 
    typealias Contained = T


let myGeneric = GenericClass<Parent>()
print("myGeneric is GenericClass<BaseClass>: \(type(of: myGeneric).Contained() is BaseClass)")

【讨论】:

好的,因为myGeneric 的类型在编译时是已知的。镜像对象中的属性呢?如果我要遍历所有属性,它们在编译时的类型是Any,但像attr.value is BaseClass 这样的东西无论如何都可以工作。但是 type(of: myGeneric).Contained() 将不起作用,因为在编译时 Any 当然没有像 Contained 这样的成员。那么,如果在编译时我们根本不知道“真实”类型,我们如何在运行时检查泛型类型呢? 听起来您需要了解如何使用协议的入门知识。我建议你对它们进行一些研究。 好吧,我想我没有明确表达我的观点。我很抱歉。我会再试一次。我正在迭代镜像对象的属性。它的所有属性类型都在编译时被称为Any。我希望其中之一是GenericClass&lt;BaseClass&gt;BaseClass 的一些子类,例如GenericClass&lt;Parent&gt;。我的BaseClass 不是协议,它只是所谓的:基类。在这种情况下,我不能调用 Contained() 构造函数,因为Any 没有这样的东西。我得到了预期的编译器错误。在这种情况下是否有可能检查泛型类型? 您的Any 对象数组并不是真正的绝对 数组。它是数量有限的类型的数组。这些类型必须都符合相同的协议。也许如果您显示更多代码,我可以帮助您。 但在您的解决方案中 BaseClass 作为协议不需要typealias Contained,这只是实现了GenericClass&lt;T: BaseClass&gt;。那么这里的协议有什么意义呢?但我想我知道你的意思。如果要求在协议中,那么编译器可能没问题。我会这样尝试。

以上是关于Swift:如何检查子类上的基类和超类的主要内容,如果未能解决你的问题,请参考以下文章

当子类和超类在不同的包中时,如何在java中继承一个类

如何将基类的未知子类放在一个数据结构中并在 C++ 中调用重写的基类函数

C#:你如何获得一个类的基类?

java中基类和超类的区别

从超类中获取子类的名称

确定子类是不是具有在 Python 中实现的基类方法