美文网首页
Day10 属性 (Properties)、方法(Methods

Day10 属性 (Properties)、方法(Methods

作者: 平凡之路561 | 来源:发表于2017-06-15 17:32 被阅读0次

本页包含内容:
• 存储属性
• 计算属性
• 属性观察器
• 类型属性

    >• 实例方法
    • 类型方法

一:属性###

1、存储属性
简单来说,一个存储属性就是存储在特定类或结构体实例里的一个常量或变量。存储属性可以是变量存储属性(用关键字 var 定义),也可以是常量存储属性(用关键字 let 定义)。可以在定义存储属性的时候指定默认值。

    //下面的例子定义了一个名为 FixedLengthRange 的结构体,该结构体用于描述整数的范围,且这个范围值在被创建后不能被修改.
    struct FixedLengthRange {
        var firstValue : Int
        let length : Int
    }
    var  rangeOfThreeItems = FixedLengthRange.init(firstValue: 0, length: 3)
    // 该区间表示整数0,1,2
    rangeOfThreeItems.firstValue = 6
    // 该区间现在表示整数6,7,8
  • 常量结构体的存储属性

// 如果创建了一个结构体的实例并将其赋值给一个常量,则无法修改该实例的任何属性,即使有属性被声明为变量也不行:

    let rangeOfFourItems = FixedLengthRange(firstValue: 0, length: 4)
    // 该区间表示整数0,1,2,3
  rangeOfFourItems.firstValue = 6
    // 尽管 firstValue 是个变量属性,这里还是会报错

这种行为是由于结构体(struct)属于值类型。当值类型的实例被声明为常量的时候,它的所有属性也就成了常量。
属于引用类型的类(class)则不一样。把一个引用类型的实例赋给一个常量后,仍然可以修改该实例的变量属性。

  • 延迟存储属性
    延迟存储属性是指当第一次被调用的时候才会计算其初始值的属性。在属性声明前使用 lazy 来标示一个延迟存储属性。

注意:
必须将延迟存储属性声明成变量(使用 var 关键字),因为属性的初始值可能在实例构造完成之后才会得到。
而常量属性在构造过程完成之前必须要有初始值,因此无法声明成延迟属性。

下面的例子使用了延迟存储属性来避免复杂类中不必要的初始化。例子中定义了 DataImporter 和 DataManager 两个类,下面是部分代码:

    class DataImporter {
        /*
         DataImporter 是一个负责将外部文件中的数据导入的类。 这个类的初始化会消耗不少时间。
         */
        var fileName = "data.txt"
        // 这里会提供数据导入功能
    }
    
    class DataManger {
        lazy var importer = DataImporter()
        var data = [String]()
    }
    let manager = DataManger()
    manager.data.append("Some data")
    manager.data.append("Some more data")
    // DataImporter 实例的 importer 属性还没有被创建

由于使用了 lazy ,importer 属性只有在第一次被访问的时候才被创建。比如访问它的属性 fileName 时:

    print(manager.importer.fileName)
    // DataImporter 实例的 importer 属性现在被创建了
    // 输出 "data.txt”

2、计算属性

    struct Point {
        var x = 0.0, y = 0.0
    }
    struct Size {
        var width = 0.0, height = 0.0
    }
    
    struct Rect {
        var origin = Point()
        var size = Size()
        var center: Point {
            get {
                let centerX = origin.x + (size.width / 2)
                let centerY = origin.y + (size.height / 2)
                return Point(x: centerX, y: centerY)
            }
            set(newCenter) {
                origin.x = newCenter.x - (size.width / 2)
                origin.y = newCenter.y - (size.height / 2)
            }
        } }
    var square = Rect(origin: Point(x: 0.0, y: 0.0),size: Size(width: 10.0, height: 10.0))
    let initialSquareCenter = square.center
    square.center = Point(x: 15.0, y: 15.0)
    print("square.origin is now at (\(square.origin.x), \(square.origin.y))")
    // 打印 "square.origin is now at (10.0, 10.0)”
  • 只读计算属性

只有 getter 没有 setter 的计算属性就是只读计算属性。只读计算属性总是返回一个值,可以通过点运算符访问,但不能设置新的值。
只读计算属性的声明可以去掉get关键字和花括号:

<pre>struct Cuboid {
var width = 0.0, height = 0.0, depth = 0.0
var volume: Double {
return width * height * depth
}
}
let fourByFiveByTwo = Cuboid(width: 4.0, height: 5.0, depth: 2.0)
print("the volume of fourByFiveByTwo is (fourByFiveByTwo.volume)")</pre>

** 3、属性观察器**
• 在新的值被设置之前调用
• 在新的值被设置之后立即调用

    class SomeClass {
        static var storedTypeProperty = "Some value."
        static var computedTypeProperty: Int {
            return 27 }
        class var overrideableComputedTypeProperty: Int {
            return 107
        }

** 4、类型属性语法**
使用关键字 static 来定义类型属性。在为类定义计算型类型属性时,可以改用关键字 class 来支持子类对父类的实现进行重写。
下面的例子演示了存储型和计算型类型属性的语法:

        struct SomeStructure {
            static var storedTypeProperty = "Some value."
            static var computedTypeProperty: Int {
                return 1
            }
        }
        
        enum SomeEnumeration {
            static var storedTypeProperty = "Some value."
            static var computedTypeProperty: Int {
                return 6
            }
        }
        
        class SomeClass {
            static var storedTypeProperty = "Some value."
            static var computedTypeProperty: Int {
                return 27
            }
            class var overrideableComputedTypeProperty: Int {
                return 107
            }
        }

二:方法(Methods)###

方法是与某些特定类型相关联的函数。类、结构体、枚举都可以定义实例方法;实例方法为给定类型的实例封装了具体的任务与功能。
类、结构体、枚举也可以定义类型方法;类型方法与类型本身相关联。

类型方法与 Objective-C 中的类方法(class methods)相似。结构体和枚举能够定义方法是 Swift 与 C/Objective-C 的主要区别之一。
在 Objective-C 中,类是唯一能定义方法的类型。但在 Swift 中,你不仅能选择是否要定义一个类/结构体/枚举,还能灵活地在你创建的类型(类/ 结构体/枚举)上定义方法。

** 1、实例方法 (Instance Methods)(-方法)**
实例方法是属于某个特定类、结构体或者枚举类型实例的方法。实例方法提供访问和修改实例属性的方法或提供与实例目的相关的功能,并以此来支撑实例的功能

实例方法要写在它所属的类型的前后大括号之间。实例方法能够隐式访问它所属类型的所有的其他实例方法和属性。
实例方法只能被它所属的类的某个特定实例调用。实例方法不能脱离于现存的实例而被调用。
下面的例子,定义一个很简单的 Counter 类, Counter 能被用来对一个动作发生的次数进行计数:

    class Counter {
        var count = 0
        func increment () {
            count += 1
        }
        func increment(by amount: Int) {
            count += amount
        }
        
        func reset() {
            count = 0
        }
    }
    //  Counter 类定义了三个实例方法:
    //   - increment 让计数器按一递增;
    //   - increment(by: Int) 让计数器按一个指 定的整数值递增;
    //   - reset 将计数器重置为0。
    
    let counter = Counter ()
    print(counter.count)
    //初始计数值是0
    counter.increment()
    print(counter.count)
    //计数值现在是1
    counter.increment(by: 5)
    print(counter.count)
    //计数值现在是6
    counter.reset()
    //计数值现在是0
    print(counter.count)

** 2、类型方法(+方法)**
实例方法是被某个类型的实例调用的方法。你也可以定义在类型本身上调用的方法,这种方法就叫做类型方法。
在方法的 func 关键字之前加上关键字 static ,来指定类型方法。
类还可以用关键字 class 来允许子类重写父类的方法实现。

    class SomeClasses {
        class func someTypeMethod () {
            //实现类型方法
            
        }
        
        static func testMethod () -> String {
            return "testMethod"
        }
    }
    //调用类型方法
    SomeClasses.someTypeMethod()
    let msg = SomeClasses.testMethod()
    print(msg)

相关文章

网友评论

      本文标题:Day10 属性 (Properties)、方法(Methods

      本文链接:https://www.haomeiwen.com/subject/dhduqxtx.html