文档章节

Swift学习—对象和类

TomatosX
 TomatosX
发布于 2015/05/20 12:29
字数 1021
阅读 71
收藏 2

class 后面跟类名来创建一个类。除了上下文是类以外,声明一个属性和常量,变量声明是一样的,方法和函数也是如此。

class Shape {
    var numberOfSides = 0
    func simpleDescription() -> String {
        return "A shape with \(numberOfSides) sides."
    }
}
试一试:

添加一个常量属性,再添加一个含一个参数的函数。

通过在类名的后面加小括号来创建这个类的实例。用点语法来访问这个实例的属性和方法。

var shape = Shape()
shape.numberOfSides = 7
var shapeDescription = shape.simpleDescription()

上个版本的Shape类缺失了一个重要的东西:通过初始化器来创建一个实例。用 init来 创建一个。

class NamedShape {
    var numberOfSides: Int = 0
    var name: String
    
    init(name: String) {
        self.name = name
    }
    
    func simpleDescription() -> String {
        return "A shape with \(numberOfSides) sides."
    }
}

值得注意的是这里用self来区分name是属性还是参数。创建一个类的实例时这里的参数传递就像函数调用时的参数传递一样。每一个属性都需要赋值,在声明的时候(如numberOfSides)或是在初始化器中(如name)。

当你需要在对象释放前做一些清理工作,可以用deinit 来创建一个析构器。

子类类名后面是父类名,中间用冒号: 隔开。没有强求子类要有标准的根类,所以可以根据需要省略父类。

子类的方法要覆盖父类方法的实现时,要用override标记,如果不加的话,编译器会报错。编译器同时也检测子类标记有override的方法是否真正的覆盖了父类方法的实现。

class Square: NamedShape {
    var sideLength: Double
    
    init(sideLength: Double, name: String) {
        self.sideLength = sideLength
        super.init(name: name)
        numberOfSides = 4
    }
    
    func area() ->  Double {
        return sideLength * sideLength
    }
    
    override func simpleDescription() -> String {
        return "A square with sides of length \(sideLength)."
    }
}
let test = Square(sideLength: 5.2, name: "my test square")
test.area()
test.simpleDescription()

试一试:

写一个继承自NameShape的子类Circle,初始化器中接收radiusname参数。并实现areadescribe方法。

除了简单的存储属性,属性还有gettersetter方法。

class EquilateralTriangle: NamedShape {
    var sideLength: Double = 0.0
    
    init(sideLength: Double, name: String) {
        self.sideLength = sideLength
        super.init(name: name)
        numberOfSides = 3
    }
    
    var perimeter: Double {
    get {
        return 3.0 * sideLength
    }
    set {
        sideLength = newValue / 3.0
    }
    }
    
    override func simpleDescription() -> String {
        return "An equilateral triagle with sides of length \(sideLength)."
    }
}
var triangle = EquilateralTriangle(sideLength: 3.1, name: "a triangle")
triangle.perimeter
triangle.perimeter = 9.9
triangle.sideLength

perimetersetter方法中,新值有一个隐式的名newValue.你可以在set方法的后面加一个括号显式的提供一个新值名字。

对于EquilateralTriangle中的初始化器做了三件事:

1.设置子类声明的属性的值

2.调用父类的初始化器

3.改变被父类定义的属性值。当然通过其他的如方法,getter,setter,都可以完成这一点。

如果你不需要计算属性但是又需要在设置一个新值之后,在运行之前提供一些代码,可以用willsetdidset。比如,下面的类确保了三角形和正方形的边长都相同。

class TriangleAndSquare {
    var triangle: EquilateralTriangle {
    willSet {
        square.sideLength = newValue.sideLength
    }
    }
    var square: Square {
    willSet {
        triangle.sideLength = newValue.sideLength
    }
    }
    init(size: Double, name: String) {
        square = Square(sideLength: size, name: name)
        triangle = EquilateralTriangle(sideLength: size, name: name)
    }
}
var triangleAndSquare = TriangleAndSquare(size: 10, name: "another test shape")
triangleAndSquare.square.sideLength
triangleAndSquare.triangle.sideLength
triangleAndSquare.square = Square(sideLength: 50, name: "larger square")
triangleAndSquare.triangle.sideLength

类中的方法和函数有一个重要的不同点,函数的参数名只能在函数中使用,但是方法中的参数名在你调用方法时还需要用上(第一个参数的参数名除外)。默认情况下,方法的参数名在调用或在方法内部使用时是相同的,你可以标识第二个名字,在方法中使用。

class Counter {
    var count: Int = 0
    func incrementBy(amount: Int, numberOfTimes times: Int) {
        count += amount * times
    }
}
var counter = Counter()
counter.incrementBy(2, numberOfTimes: 7)

当用到optional值时,你可以在操作之前加一个问号。如果在之前的值是nil,那么问号之后的代码就被忽略,都被视为是nil。否则,这个optional值被解包,问号之后的就作为解包值。下面两种情况下,整个表达式的值都是一个optional值。

let optionalSquare: Square? = Square(sideLength: 2.5, name: "optional square")
let sideLength = optionalSquare?.sideLength

本文转载自:http://blog.csdn.net/chenpolu/article/details/30243997

TomatosX
粉丝 22
博文 207
码字总数 119547
作品 0
成都
iOS工程师
私信 提问
swift4.1 系统学习十七 类(一)

// // main.swift // swift17(类) // // Created by iOS on 2018/10/25. // Copyright © 2018年 weiman. All rights reserved. // import Foundation /* 新的业务需求忙了几天,有点空闲,继......

小曼Study
2018/10/25
0
0
你没看错:Swift可以直接调用Python函数库

上周Perfect又推出了新一轮服务器端Swift增强函数库:Perfect-Python。对,你没看错,在服务器端Swift 其实可以轻松从其他语种的函数库中直接拿来调用,不需要修改任何内容。如果没有类似经验...

rockford
2017/08/30
0
0
swift4.1 系统学习十四 协议

// 协议 / OC中也有协议,swift中的协议的作用与OC中基本一样,只是在写法上有一点区别。 我们使用 protocol关键字来定义一个协议。在一个协议中只能存放计算式属性以及方法的声明, 而不能对...

小曼Study
2018/10/18
0
0
Swift专题讲解十六——ARC在Swift中的应用

Swift专题讲解十六——ARC在Swift中的应用 一、引言 ARC(自动引用计数)是Objective-C和Swift中用于解决内存管理问题的方案。在学习Objective-C编程时经常会学习到一个关于ARC的例子:在一个...

珲少
2016/05/20
1K
1
从 Objective-C 到 Swift —— Swift 糖果

Swift带来很多确实很棒的特性,使得很难再回到Objective-C。主要的特性是安全性,不过这也被看成是一种额外副作用。 带类型接口的强型别 Swift有强型别,这意味着除非你要求,不然Swift不会为...

oschina
2014/06/27
9.4K
18

没有更多内容

加载失败,请刷新页面

加载更多

Jenkins系列_插件安装及报错处理

进入Jenkins之后我们可以进行插件的安装,插件管理位于以下模块: 发现上面报了一堆错误,是因为插件的依赖没有安装好,那么这一节,就先把这些错误解决掉吧。解决完成后,也就基本会使用插件...

shzwork
今天
2
0
mysql mysql的所有查询语句和聚合函数(整理一下,忘记了可以随时看看)

查询所有字段 select * from 表名; 查询自定字段 select 字段名 from 表名; 查询指定数据 select * from 表名 where 条件; 带关键字IN的查询 select * from 表名 where 条件 [not] in(元素...

edison_kwok
昨天
9
0
多线程同时加载缓存实现

import com.google.common.cache.Cache;import com.google.common.cache.CacheBuilder;import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorServi......

暗中观察
昨天
3
0
利用VisualVM 内存查看

准备工作,建几个测试类。等下就是要查看这几个类里面的属性 package visualvm;public class MultiObject { private String str; private int i; MultiObject(String str...

冷基
昨天
2
0
组装一台工作游戏两用机

一、配置清单如下: 分类 项目 价格(元) 主板 华硕(ASUS)TUF Z370-PLUS GAMING II 电竞特工 Z370二代 支持9代CPU 1049 CPU 英特尔(Intel) i7 8700K 酷睿六核 盒装CPU处理器 2640 风扇 九...

mbzhong
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部