如何在Swift中隐藏继承的方法

时间:2018-12-18 17:04:16

标签: ios swift

我有一个Child类,其中包含我定义的方法以及从其Parent类继承的方法。我希望用户无法使用Parent的某些方法,或者至少使用 会产生编译错误/警告。示例:

class Parent {
    public func secretMethod() { // Don't want anyone to use
    }
}

class Child: Parent {
    public func overtMethod() { // Fine with people using
    }
}

Child.init().overtMethod()  // Fine
Child.init().secretMethod() // Not Fine. Should not be viewable/useable/accessible

我无法更改父班。我多么渴望能够将secretMethod设置为private。 Swift不允许在覆盖函数时限制访问级别,因此我也无法在Child类中将secretMethod设置为private

到目前为止,我一直在使用@available用编译警告和消息标记该方法,但是我希望有更好的方法吗?我考虑了覆盖并引发错误,但是如果原始方法未标记为throws,则无法做到这一点。

谢谢。

编辑:我也不能覆盖secretMethod使其不可用。 Child类需要访问它。

4 个答案:

答案 0 :(得分:2)

如果您不想公开父类的公共方法,请不要使用继承。您可以将“父”类隐藏为“子”类中的私有实例,并且仅转发要公开的方法。

如果由于子类继承父类而依赖于子类的继承,那么您也不能将任何父方法设为私有。如果您传递子类(这会隐藏以前的公共父方法),则会破坏使用父类的API之间的契约。那行不通。

答案 1 :(得分:2)

重新考虑您的设计。

我认为您可能只考虑“用户”(另一位开发人员?我想您正在编写库?),而不是 现有资源 。子类的基本思想是,可以在使用父类的任何地方使用子类。

class A: UIView {
  func availableMethod() {
  }
  // func layoutSubviews() ----- let's say you want to hide this method
}

这里出现问题是因为您不知道layoutSubviews可能有其他内部类在做什么,并且如果您以某种方式在A的实例上对其进行了阻止,那么任何期望能够使用的东西该实例就好像是UIView的实例一样,现在将失败。

答案 2 :(得分:1)

看起来,您正在寻找的是protected访问修饰符,该修饰符使您可以在其后代中看到方法和变量。

但是,在Swift中没有任何东西。主要访问修饰符为privateinternal

它们之间的某个位置是fileprivate。它使您可以在一个文件中包含可见的方法和变量。即使这对您来说是解决方案,也可能不是正确的设计模式。


如果您正在编写库,并且不想允许其他程序员从 parent 调用方法,但是想让他们看到 subclasses'方法,您可以在 subclass

中将internal函数从 parent 覆盖为publicopen函数

答案 3 :(得分:1)

我想增强@nikwest的答案。您应该尝试使用合成而不是继承。因此,ParentChild根本不需要共享任何代码,但是两种方法都可以使用。您还可以创建一个共同的祖先,以便某个var将始终存在。

class Parent: Overt {
}

class Child: Overt, Secret {
}

protocol Overt { 
    func overtMethod() 
}
protocol Secret {
    func secretMethod() 
}

extension Overt {
    public func overtMethod() { // stuff }
}

extension Secret {
    public func secretMethod() { // stuff }
}

当您要共享一个公用var或某些东西(例如使用合成模式的UIViewController)时,可以使用具有变体的CommonParent然后是{{ 1}}和Child1将添加实现所需功能所需的协议。如果您没有在Child2中使用默认实现,则仍然可以覆盖。