简体   繁体   English

如何快速声明“受保护”变量

[英]How to declare a 'protected' variable in swift

I want to create a class that inherits from another class, which is in a different file.我想创建一个从另一个类继承的类,该类位于不同的文件中。

For example:例如:

Class1.swift Class1.swift

class Class1
{
    protected var 
    //Do Stuff
}

Class2.swift Class2.swift

class Class2:Class1
{
    //Do stuff
}

How would I be able to have access to a 'protected' variable/function in swift?我如何能够快速访问“受保护”的变量/函数?

When I declare a private variable/function, I can only use it in that class.当我声明一个私有变量/函数时,我只能在那个类中使用它。 If I use 'fileprivate', my other class HAS to be in the same file as Class1 .如果我使用'fileprivate',我的另一个类必须与Class1位于同一个文件中。 What I want to do is keep my classes in separate files and use the Groups from within Xcode to know what class belongs with which category.我想要做的是将我的类保存在单独的文件中,并使用 Xcode 中的组来了解哪个类属于哪个类别。

You would have to use internal for that as Swift doesn't offer a protected keyword (unlike many other programming languages).您必须为此使用internal ,因为 Swift 不提供protected关键字(与许多其他编程语言不同)。 internal is the only access modifier between fileprivate and public : internalfileprivatepublic之间唯一的访问修饰符:

Internal access enables entities to be used within any source file from their defining module, but not in any source file outside of that module.内部访问使实体可以在来自其定义模块的任何源文件中使用,但不能在该模块之外的任何源文件中使用。 You typically use internal access when defining an app's or a framework's internal structure.在定义应用程序或框架的内部结构时,您通常会使用内部访问。

There is a blog post that explains a little bit more about why the language designers chose not to offer a protected keyword (or anything equivalent).有一篇博客文章解释了为什么语言设计者选择不提供protected关键字(或任何等效的东西)。

Some of the reasons being that一些原因是

It doesn't actually offer any real protection, since a subclass can always expose “protected” API through a new public method or property.它实际上并没有提供任何真正的保护,因为子类总是可以通过新的公共方法或属性公开“受保护的”API。

and also the fact that protected would cause problems when it comes to extensions, as it wouldn't be clear whether extensions should also have access to protected properties or not.还有一个事实,即protected在扩展方面会导致问题,因为不清楚扩展是否也应该访问protected属性。

Even if Swift doesn't provide protected access, still we can achieve similar access by using fileprivate access control.即使 Swift 没有提供protected访问,我们仍然可以通过使用文件fileprivate访问控制来实现类似的访问
Only thing we need to keep in mind that we need to declare all the children in same file as parent declared in.我们唯一需要记住的是,我们需要在与父项声明的同一文件中声明所有子项。

Animal.swift Animal.swift

import Foundation

class Animal {
    fileprivate var protectedVar: Int = 0
}

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

OtherFile.swift其他文件.swift

let dog = Dog()
dog.doSomething()

Use an underscore for such protected variables :/对此类受保护的变量使用下划线:/

That's about it ...就是这样...

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


class FlightMap: RawDisplayThing() {

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

Everyone has to "just agree" that only the concept class can use the "_" variables and functions.每个人都必须“同意”只有概念类可以使用“_”变量和函数。

At least, it's then relatively easy to search globally on each "_" item and ensure it only used by the superclasses.至少,在每个“_”项目上进行全局搜索并确保它只被超类使用是相对容易的。

Alternately, prepend say "local", "display", or possibly the name of the class (or whatever makes sense to your team) to such concepts.或者,在这些概念之前加上“本地”、“显示”或类的名称(或任何对您的团队有意义的名称)。

class RawDisplayThing {
    
    var rawDisplayFraction: ...
    var rawDisplayTrigger: ...
    var rawDisplayConvolution: ...

etc etc. Maybe it helps :/等等等等。也许它有帮助:/

If you dont want to have both classes belonging to the same file, here is what you can do:如果您不想让两个类都属于同一个文件,您可以执行以下操作:

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

Then on the child class:然后在子类上:

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

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

The next best thing in my opinion would be to have both classes in the same file and use fileprivate instead.在我看来,下一个最好的事情是将两个类都放在同一个文件中并使用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" 
   }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM