如何在swift中声明一个'protected'变量

时间:2017-01-20 13:36:03

标签: swift class swift3 encapsulation

我想创建一个继承自另一个类的类,该类位于不同的文件中。

例如:

Class1.swift

class Class1
{
    protected var 
    //Do Stuff
}

Class2.swift

class Class2:Class1
{
    //Do stuff
}

我怎么能在swift中有一个'保护'的变量/函数?

当我声明一个私有变量/函数时,我只能在该类中使用它。如果我使用'fileprivate',我的其他类必须在保存文件中作为Class1。我想要做的是将我的类保存在seporate文件中,并使用Xcode中的Groups来了解哪个类属于哪个类别。

5 个答案:

答案 0 :(得分:35)

你必须使用internal,因为Swift没有提供protected关键字(与许多其他编程语言不同)。 internalfileprivatepublic之间唯一的访问修饰符:

  

内部访问使实体可以在任何源文件中使用   来自他们的定义模块,但不在其他任何源文件中   模块。您通常在定义应用程序或a时使用内部访问权限   框架的内部结构。

有一个blog post更多地解释了为什么语言设计师选择不提供protected关键字(或任何等效关键字)。

其中一些原因是

  

它实际上并没有提供任何真正的保护,因为子类可以   始终通过新的公共方法或属性公开“受保护的”API。

以及protected在扩展方面会出现问题这一事实,因为它不清楚扩展是否也应该可以访问protected属性。

答案 1 :(得分:4)

即使Swift未提供protected访问权限,我们仍然可以通过fileprivate访问控制实现类似的访问权限。 我们唯一需要记住的是,我们需要将所有子节点声明为与父节点相同的文件。

<强> Animal.swift

import Foundation

class Animal {
    fileprivate var protectedVar: Int = 0
}

class Dog: Animal {
    func doSomething() {
        protectedVar = 1
    }
}

<强> OtherFile.swift

let dog = Dog()
dog.doSomething()

答案 2 :(得分:2)

对这些受保护的变量使用下划线:/

就是这样...

class RawDisplayThing {

    var _fraction: CGFloat = 0 {
        didSet { ... }
    }


class FlightMap: RawDisplayThing() {

    var currentPosition() {
        ...
        _fraction = 
        ...
    }
}

每个人都必须“完全同意”,只有概念类才能使用“ _”变量和函数。

至少,然后相对容易地在每个“ _”项上进行全局搜索,并确保仅由超类使用。

或者,在此类概念的前面加上“本地”,“显示”或类名(或对您的团队有意义的类)。

class RawDisplayThing {

    var rawDisplayFraction: ...
    var rawDisplayTrigger: ...
    var rawDisplayConvolution: ...

etc等。也许有帮助:/

答案 3 :(得分:0)

我认为第二个最好的办法是将两个类都放在同一个文件中,而改用fileprivate

class Class1 {
   fileprivate var foo: String
}

final class Class2: Class1 {
   func bar() {
      // Class1.foo is accessible from Class1 but nothing else
      self.foo = "bar" 
   }
}

答案 4 :(得分:0)

如果您不想让两个类都属于同一个文件,您可以这样做:

class Parent {
    internal private(set) var myProtectedBoolean = false
}

然后在子类上:

class Child: Parent {
   private var _myProtectedBoolean: Bool = false;

   override var myProtectedBoolean: Bool {
       get { return _myProtectedBoolean }
       set { _myProtectedBoolean = newValue }
   }
}