Swift学习笔记

Swift - 方法

2022-03-16  本文已影响0人  aven_kang
截屏2022-02-19 下午4.31.08.png

mutating

结构体和枚举类型,默认情况下,值类型的属性不能被自身的实例方法修改
如果需要修改,需要在方法前添加mutating关键字
struct Point {
  var x = 0.0, y = 0.0
  mutating func moveBy(deltaX : Double, deltaY : Double) {
          x += deltaX
          y += deltaY
     }
}

枚举也是同理的

enum StateSwitch {
    case low,middle,high
    mutating func next() {
      switch self {
        case .low:
              self = .middle
        case .middle:
              self = .high
        case .high:
              self = .low
      }
  }
}

不加mutating是会报错的

discardableResult

struct Point {
  var x = 0.0, y = 0.0
  mutating func moveBy(deltaX: Double)  -> Double{
          x += deltaX
          y += deltaY
     }
}

在上述代码中,方法会返回一个Double值
如果我们在调用的时候

var p = Point()
p.moveBy(deltaX:10) // 这行是会出现黄色警告⚠️,告诉你这个返回值,你没有使用

如果你在方法前加入了@discardableResult

struct Point {
  var x = 0.0, y = 0.0
  @discardableResult mutating func moveBy(deltaX: Double)  -> Double{
          x += deltaX
          y += deltaY
     }
}

这样就不会有那个警告出现了

下标

使用subscript可以给任意类型(枚举,类,结构体)增加下标功能,有些地方也称之为:下标脚本
subscript的语法类似于实例方法,计算属性,本质就是方法(函数)
class Point {
        
        var x = 0.0
        var y = 0.0
        subscript(index:Int) -> Double {
            
            set {
                
                if index == 0 {
                    x = newValue
                }else if index == 1 {
                    y = newValue
                }
                
            }
            get {
                
                if index == 0 {
                    return x
                }else if index == 1 {
                    return y
                }
                return 0.0
            }
        }
    }

在调用的时候

 var p = Point()
     p[0] = 1.0  // set方法
     p[1] = 2.0  // set方法
     print(p[0]) // get方法

用起来跟数组的感觉是一样的

1.subscript中定义的返回值决定了get方法set方法返回的类型
2.subscript可以接受多个参数,并且类型任意

下标的细节

class Point {
        
        var x = 0.0
        var y = 0.0
        subscript(index:Int) -> Double {
            get {
                
                if index == 0 {
                    return x
                }else if index == 1 {
                    return y
                }
                return 0.0
            }
        }
    }
1.subscript可以没有set方法,但不能没有get方法
2.如果只有get方法,相当于是只读属性,不能修改
2.如果只有get方法,可以省略get
class Point {
        
        var x = 0.0
        var y = 0.0
        subscript(index:Int) -> Double {
                if index == 0 {
                    return x
                }else if index == 1 {
                    return y
                }
                return 0.0
            }
    }
可以设置参数标签
class Point {
            
            var x = 0.0
            var y = 0.0
            subscript(index i:Int) -> Double {
                
                set {
                    
                    if i == 0 {
                        x = newValue
                    }else if i == 1 {
                        y = newValue
                    }
                    
                }
                get {
                    
                    if i == 0 {
                        return x
                    }else if i == 1 {
                        return y
                    }
                    return 0.0
                }
            }
        }
 var p = Point()      
 p[index: 1]
下标可以是类方法
class Point {
            
        var x = 0.0
        var y = 0.0
        static subscript(index v1:Int,index v2:Int) -> Double {
                
                set {
                    
                    
                }
                get {
                    
                    
                    return 0.0
                }
            }
        }
Point[index: 10, index: 20]
截屏2022-02-19 下午7.51.39.png

结构体,类作为返回值的对比

如果返回值是一个结构体,是需要补上set方法,因为结构体是值类型,是需要进行拷贝的,既然拷贝了新的一份,那么就无法访问到了原来的那一份,而类是引用类型,可以根据指针访问到。

重写类型方法、下标

class Animal {
        
        class func speak() {
            print("animal speak")
        }
        
        class subscript(index i:Int) -> Int {
            return i;
        }
        
    }
    
    class Cat : Animal {
        
        override class func speak() {
            super.speak()
            print("cat speak")
        }
        
        override class subscript(index i: Int) -> Int {
            return super[index: i] + 1
        }
    }
在上述代码中,父类的类方法,如果是被class修饰的,在子类中是可以重写,如果父类的类方法是被static修饰的,在子类是不能被重写的,如下图的展示
截屏2022-02-19 下午9.01.06.png

但是,如果子类可以把父类的方法重写为static

 class Animal {
        
        class func speak() {
            print("animal speak")
        }
        
        class subscript(index i:Int) -> Int {
            return i;
        }
        
    }
    
    class Cat : Animal {
        
        override static func speak() {
            super.speak()
            print("cat speak")
        }
        
        override class subscript(index i: Int) -> Int {
            return super[index: i] + 1
        }
    }

在上述代码中,Cat的speak方法,被修饰成了static,并不会报错,但是继承Cat的子类,就无法重写这个方法了

重写实例属性

截屏2022-02-19 下午10.57.49.png
截屏2022-02-19 下午10.58.33.png
截屏2022-02-19 下午10.59.21.png

属性观察器

可以在子类中为父类增加属性观察器
class Circle {
    var radius: Int = 1
}

class SubCircle : Circle {
  override var radius:Int {
  willSet {
        print("SubCircleWillSet",newValue)
      }
  didSet {
        print("SubCircleDidSet",oldValue,radius)
      }
  }
}
截屏2022-02-19 下午11.26.11.png

Final

1.被final修饰的方法、下标、属性,禁止被重写
2.被final修饰的类,禁止被继承
class ClassA {
    class func func1() -> String {
        return "func1"
    }

    static func func2() -> String {
        return "func2"
    }

    class final func func3() -> String {
        return "func3"
    }
}

class ClassB : ClassA {
    override class func func1() -> String {
        return "func1 in ClassB"
    }

    // ERROR: Cannot override static method
    override static func func2() -> String {
        return "func2 in ClassB"
    }
    // ERROR: Class method overrides a 'final` class method
    override class func func3() -> String {
        return "func3 in ClassB"
    }
}
上一篇下一篇

猜你喜欢

热点阅读