ios - 在 Swift 中,如何防止函数在子类上被调用?

标签 ios swift inheritance

我有一个基类,它在一些数据结构中存储了很多其他数据对象,这个类通过一组 add/remove 使我的数据结构保持同步的函数。

现在我去创建这个基类的子类,子类就像基类一样,除了它对接受什么样的数据对象有特殊的规则(它查看数据对象的值,然后拒绝它们如果值不正确)。由于这种“有效性”检查,我为名为 change 的子类创建了一个新函数。在 change 函数中,它检查所有传入的数据对象并验证它们是否正常,然后用这些数据对象替换数据结构中的所有数据对象。

问题是我不希望有人能够创建一个子类对象并允许他们调用基类的add/remove函数,因为我只希望子类能够通过子类的change函数改变。

我还没有找到一个好的方法来“禁止”在子类中使用那些基类函数。我可以重写 函数并实现空的实现,但是没有向调用者反馈该函数没有执行任何操作。如果我使用类似 fatalError 的东西,那不是编译时间,而是运行时间。

我的其他想法是将基类的功能分解为多个协议(protocol),并将基类更改为仅具有所有数据结构,但不符合任何协议(protocol),然后有多个子类,其中一个需要add 功能可以从基础继承并另外符合 add 协议(protocol),但不需要 addremove 可以从基础继承,并且不符合任何协议(protocol),而是创建自己的 change 函数来修改数据结构。

这里有一个更简单的层次结构来解释:

class Parent {
  
  func doThis() { print("Parent Did This") }
  func doThat() { print("Parent Did That") }
  
}

class Child: Parent {
  
  override func doThis() {
    print("Child Did This")
  }
  
  // I want this to be a compile time error
  override func doThat() {
    print("Not Supported")
    return
  }
  
}

有没有更简单的方法来“隐藏”子类中的函数?

编辑 1

为了更好地解释我提出的解决方案,以及是否有更简单的方法来使用我当前的层次结构来实现它,下面是使用某些协议(protocol)的层次结构必须看起来的样子:

protocol CanDoThis {
  func doThis()
}

protocol CanDoThat {
  func doThat()
}

class Parent {
  // Important properties that all children should have
  var property1: Int = 0
  var property2: String = ""
}

class Child1: Parent, CanDoThis {
  func doThis() { print("Child1 Can Do This") }
}

class Child2: Parent, CanDoThat {
  func doThat() { print("Child2 Can Do That") }
}

class Child3: Parent, CanDoThis, CanDoThat {
  func doThis() { print("Child3 Can Do This") }
  func doThat() { print("Child3 Can Do That") }
}

最佳答案

免责声明

协议(protocol)版本可能会设计得更好 - 请参阅 Liskov Substitution Principle加上你提到的其他事情。

回答问题

您可以使用属性 @available()(参见 Swift -> Language Reference -> Attributes)。

class Parent {
    func doThis() { print("Parent Did This") }
    func doThat() { print("Parent Did That") }
}

class Child: Parent {
    override func doThis() {
        print("Child Did This")
    }

    @available(*, unavailable, message:"Child can't doThat")
    override func doThat() {
        print("Not Supported")
    }
}


let parent = Parent()
parent.doThis()
parent.doThat()

let child = Child()
child.doThis()
child.doThat()

您在 child.doThat() 上收到以下错误消息:

'doThat()' is unavailable: Child can't doThat

不过,您可以通过执行以下操作来解决这个问题(再次参见 Liskov 替换原则):

let maybeChild: Parent = Child()
maybeChild.doThis()
maybeChild.doThat()

关于ios - 在 Swift 中,如何防止函数在子类上被调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34802374/

相关文章:

ios - UIWebView - CFData 何时(或如何)发布?

Swift 2 - 打开分割 View Controller

c++ - 创建对象数组 - 从类模板继承并使用 C++ 中的构造函数

ios - 将 iOS 应用程序版本还原为旧版本

objective-c - NSMutableArray 和副本

ios - 多 View Controller 和 segue 导航错误消息我不明白

ios - 如何在 Swift 中删除属于同一对象的所有对象

ios - 滚动 UITableView 时随机崩溃

C# 继承窗体中的类

Java 泛型 : create a general method operating on parent classes