【问题标题】:How to override private var in superclass如何覆盖超类中的私有变量
【发布时间】:2016-02-28 12:50:54
【问题描述】:

所以我有以下超类:

class Vehicle {

    private var _maxSpeed: Int = 100

    var maxSpeed: Int {
        get {
            return _maxSpeed
        }

var tooFast: Bool {
        get {
            if maxSpeed >= 140 {
                return false
            } else {
                return true
            }
        }
    }
}

另外,我有一些子类,我想在其中覆盖 maxSpeed... 每个示例:

class SuperCar: Vehicle {
//override the maxspeed...

}

但是我应该如何处理呢?还是只有在我们不将其设为私有时才有可能?我试图将私密部分扔出窗外,但效果不佳...

class Vehicle {

    var maxSpeed: Int = 100

var tooFast: Bool {
        get {
            if maxSpeed >= 140 {
                return false
            } else {
                return true
            }
        }
    }
}

class SuperCar: Vehicle {
// override the maxSpeed...
override var maxSpeed: Int = 200
// Will not work...
}

【问题讨论】:

    标签: swift class subclass private superclass


    【解决方案1】:

    对于 Rob 答案的 Swift 3 版本,您不能覆盖私有,但有趣的是,您可以使用 fileprivate 计算属性。但是,您必须将类放在同一个文件中。

    我今天做了这个:

    protocol Renderer {
    }
    
    class BaseClass {
         private let _renderer: Renderer = BaseClassRenderer()
         fileprivate var renderer: Renderer {
             return _renderer
         }
    }
    
    class Subclass: BaseClass {
         private let _renderer: Renderer = SubclassRenderer()
         override fileprivate var renderer: Renderer {
             return _renderer
         }
    }
    

    【讨论】:

      【解决方案2】:

      只需将类和子类放在同一个文件中。 private 与继承无关。它与文件范围有关。同一文件中的任何内容都可以访问private 成员。

      也就是说,您几乎可以肯定不应该在这里使用继承。 Vehicle 几乎可以肯定是一个协议。这样你就不会有继承或private 的任何头痛。

      protocol Vehicle {
          var maxSpeed: Int {get}
      }
      
      extension Vehicle {
          // Default implementation if none is given
          var maxSpeed: Int { return 100 }
      
          // Another method that applies to all Vehicles
          var tooFast: Bool {
              return maxSpeed < 140 // (feels like this should be >= 140, but matching your code)
          }
      }
      
      struct SuperCar: Vehicle {
          // override the default implementation for the protcocol
          var maxSpeed = 200
      }
      

      【讨论】:

        【解决方案3】:

        在 init 方法中设置你的私有成员变量

        class Vehicle{
            private var maxSpeed: Int
            init(maxSpeed: Int = 100){
                self.maxSpeed = maxSpeed
            }
        }
        
        class SuperCar: Vehicle {
            override init(maxSpeed: Int = 200){
                super.init(maxSpeed: maxSpeed)
            }
        }
        

        【讨论】:

          【解决方案4】:

          你可以覆盖计算属性

          class C {
              var a: Int { return 10 }
          }
          class D:C {
              override var a: Int  { return 100 }
          

          【讨论】:

          • 和?问题是关于私有财产
          • @Gargo :-) 检查问题,尤其是“...我有一些子类要覆盖 maxSpeed...”,并检查其他答案以查看上下文。跨度>
          • 重读问题... 1)"只有在我们不将其设为私有的情况下才有可能?"; 2)我经常遇到同样的问题。很多初学者在阅读有关 OOP 的书籍时看到“私有修饰符很酷”,然后用他们的劣质代码向 github 发送垃圾邮件。如果您遇到问题,您不能简单地修复它,因为几乎所有代码都标记为“私有”。同时,您的答案中没有关于私有/公共修饰符的解释 - 您只是发布了一段与问题无关的代码
          • @Gargo 你知道为什么需要覆盖私有计算属性吗?您认为接受的答案更好吗?从我的角度来看,即使是 Rob 的回答也好不了多少。我的观点是“做最简单的方法!”不要试图重新评估装备。
          猜你喜欢
          • 2010-11-29
          • 2018-07-08
          • 2013-03-10
          • 1970-01-01
          • 2013-01-15
          • 1970-01-01
          • 2015-10-14
          • 2011-05-25
          • 2015-08-03
          相关资源
          最近更新 更多