官文:从今天开始开发iOS应用(Swift)第一章4~5节纯中文
来源:互联网 发布:matlab和python 编辑:程序博客网 时间:2024/06/05 00:38
1.4 Functions and Methods:函数和方法
1.4.1 函数(function)
函数:指的是一段有名字的,可重用的代码段。它可被用在程序中的许多地方。
使用func来声明一个函数(function)。函数可包含0到多个参数,以”名字:类型”的格式书写。函数参数的作用是当函数调用时,可传递更多的信息到函数中。函数也可以有返回值,写在“->”后面。返回值的作用是当函数调用结束时,返回函数调用的结果。而函数的实现则是写在大括号内:
func greet(name: String, day: String) -> String { return "Hello \(name), today is \(day)."}
使用函数名后面跟上参数列表的形式来调用函数,只有第一个参数不用写参数名:
greet("Anna", day: "Tuesday")greet("Bob", day: "Friday")greet("Charlie", day: "a nice day")
1.4.2 方法(method)
在一个特定类中定义的函数称为方法(method)。方法被显式绑定到该特定类上,也只能被该类所调用(或是该类型的子类)。在之前的例子中,有一个String类型的方法:hasSuffix(),如下所示:
let exampleString = "hello"if exampleString.hasSuffix("lo") { print("ends in lo")}
如你所见,使用点操作符“.”来调用该类型中的方法。
调用时第一个参数省略参数名,其余各个参数都必须写上名称。例如下面代码中,该方法有两个参数,只写出第二个参数的名称“atIndex:”(代码可读性得到很大提升):
var array = ["apple", "banana", "dragonfruit"]array.insert("cherry", atIndex: 2)array
1.5 Classes and Initializers:类和构造器
在面向对象编程中,程序活动大多都依赖于程序内部对象之间的交互。
对象(object):是类的实例化产物。
类(class):可以理解为是该对象的蓝图。
在类中使用属性(property)来存储它自身的额外信息,并且由方法(method)来定义它的行为。
1.5.1 类的定义
使用class后面跟上类名来定义一个类。而类属性的声明语法和常量变量的声明语法类似,不同之处仅在于它们是在类中声明的。类中方法的声明和函数声明类似。
下面的代码中声明了一个Shape类,它有一个numberOfSides属性,并且有一个simpleDescription()方法:
class Shape{ var numberOfSides = 0 func simpleDescription() -> String { return "A shape with \(numberOfSides) sides." }}
1.5.2 对象的定义及访问
创建一个类的实例,即创建一个对象。
创建方法是在类名之后加上括号“()”,使用点操作符来访问所创建的实例的属性和方法。这里,shape是一个Shape类实例化出来的对象:
var shape = Shape()shape.numberOfSides = 7var shapeDescription = shape.simpleDescription()
1.5.3 构造器(initializer)
Shape类中还缺少一个重要内容:构造器(initializer)。
构造器实际是类的方法,它可用于初始化类的实例对象。包括初始化所有属性,以及完成一些其他的初始化工作。
您可以使用init来创建一个构造器。
下面例子中定义了一个NamedShape类,它含有一个构造器,构造器接收一个name参数:
class NamedShape{ var numberOfSides = 0 var name: String init(name: String) { self.name = name } func simpleDescription() -> String { return "A shape with \(numberOfSides) sides." }}
这里使用self关键字来区分类的属性名name和构造器参数名name。
所有的属性都需要被赋值(在声明时赋值,或是在构造器中进行赋值)。
在类名后面加上括号来调用构造器,而不需要使用init来调用它。当调用构造器时,需要写出所有的参数名,如下所示:
let namedShape = NamedShape(name: "my named shape")
1.5.4 类的继承(inherit)和方法覆盖(override)
通过继承(inherit),一个类可以拥有另外一个类行为。被继承的类称为父类(superclass),而继承了父类行为的类称为子类(subclass)。继承的语法格式为:子类名:父类名。一个子类只能继承一个父类,以此类推,从而构成了一个树状的继承层次关系。
子类中的方法覆盖父类中同名方法时,需要写上override,若在覆盖时不写override,则编译器会报错。另外,编译器也会检查那些写了override的,但实际上并没有覆盖父类方法的子类方法。
下面的代码中定义了Square类,它是NamedShape的子类:
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 testSquare = Square(sideLength: 5.2, name: "my test square")testSquare.area()testSquare.simpleDescription()
1.5.5 构造器的写法
需要注意,Square类的构造器进行了三个步骤:
- 设置Square类属性sideLength;
- 调用父类NamedShape的构造器;
- 修改父类NamedShape的属性numberOfSides。
这样可以完成更多的初始化工作。
实际上,有时需要初始化工作不总是成功,因为如果提供了超出范围的初始化参数,则会初始化出错误的对象。
有时可能会初始化对象失败的构造器称为可失效构造器(failable initializer)。一个可失效构造器有可能返回nil。使用init?来声明一个可失效构造器:
class Circle: NamedShape { var radius: Double init?(radius: Double, name: String) { self.radius = radius super.init(name: name) numberOfSides = 1 if radius <= 0 { return nil } } override func simpleDescription() -> String { return "A circle with a radius of \(radius)." }}let successfulCircle = Circle(radius: 4.2, name: "successful circle")let failedCircle = Circle(radius: -7, name: "failed circle")
构造器可以有一些相关扩展。指定构造器(designated initializer)指示它是类的一个主要构造器。任何的类构造器最终都要调用指定构造器。一个快捷构造器是一个次要的构造器,它主要用于添加额外行为或进行自定义操作,但是也必须最终调用指定构造器。这主要和次要构造器分别使用designate和convenience关键字进行定义。
如果在构造器后面跟上了required关键字,则表示每一个该类的子类都必须重写该构造器。
1.5.6 对象类型转换
类型转换是一个检测对象类型的方法,即将该对象看作是它的继承层次中的另外的父类或子类对象来对待。
某类型的常量或变量可能实际是该类的子类实例(父类指针引用子类对象)。如果你遇到这样的情况,你可以尝试使用类型转换操作符将它向下类型转换为子类类型。
由于向下类型转换可能会失败,故类型转换操作符有两种不同的形式。第一种是可选类型的形式,即“as?”,它返回一个你尝试转换的目标类型对应的可选类型值。第二种是强制转换形式,即“as!”,尝试转换并强制解包。
如果你认为类型转换可能会失败,则使用可选类型转换操作符“as?”。这种形式的类型转换总会返回一个可选类型结果,如果转换失败,则会返回nil。你可以通过返回结果来查看转换是否成功。
如果你确信类型转换一定成功,则可以使用强制类型转换操作符“as!”。但如果转换不成功,则这个形式的向下类型转换将导致运行时错误。
下面例子中使用可选类型转换操作符检查shape数组中的每一个shape对象是一个circle还是一个square。如果对应形状找到,则计数器加一,最后打印计数结果:
class Triangle: NamedShape { init(sideLength: Double, name: String) { super.init(name: name) numberOfSides = 3 }}let shapesArray = [Triangle(sideLength: 1.5, name: "triangle1"), Triangle(sideLength: 4.2, name: "triangle2"), Square(sideLength: 3.2, name: "square1"), Square(sideLength: 2.7, name: "square2")]var squares = 0var triangles = 0for shape in shapesArray { if let square = shape as? Square { squares++ } else if let triangle = shape as? Triangle { triangles++ }}print("\(squares) squares and \(triangles) triangles.")
- 官文:从今天开始开发iOS应用(Swift)第一章4~5节纯中文
- 官文:从今天开始开发iOS应用(Swift)第一章1~3节纯中文
- 官文:从今天开始开发iOS应用(Swift)第一章1~3节中英对照
- 从今天开始学习Swift -- Swift 初见
- ios应用开发流程——Start Developing iOS Apps Today——从今天开始开发IOS(IOS7版)系列源文档翻译(七)
- iOS应用开发 - 从开始到结束
- 基础教程5——Start Developing iOS Apps Today——从今天开始开发IOS(IOS7版)系列源文档翻译(六)
- 基础教程4——Start Developing iOS Apps Today——从今天开始开发IOS(IOS7版)系列源文档翻译(五)
- 从今天开始学习iOS开发(iOS 7版)--实现一款App之Foundation框架的使用
- IOS - 0 -今天开始学IOS开发
- 从新开始——Start Developing iOS Apps Today——从今天开始开发IOS(IOS7版)系列源文档翻译(一)
- ios开发 - Swift中文教程
- FireFox应用开发详解第一章-如何开始
- 从今天起开始学习Swift Hello,world
- 从今天开始 好好学开发
- 从今天开始写开发日志了
- 从今天开始,记录开发经历
- 今天开始学习swift
- Anroid 加载图片方式一 使用SmartImageView
- 使用SQl方法把多行字符直接转换成相应的表输出
- 全端工程师必备技能汇总
- ZOJ 3946 Highway Project(Dijkstra)
- 优先级队列
- 官文:从今天开始开发iOS应用(Swift)第一章4~5节纯中文
- 训练深度神经网络的时候需要注意的技巧
- XDU-1138 Z1+Z2 (水~复数相加) From 西电校赛网络赛
- 庖丁解牛之仿《闪传》实现文件传输(中)
- "软件包 opera-stable 需要重新安装,但是我无法找到相应的安装文件 " 解决办法
- android Gradle的神奇之处
- BZOJ1338: Pku1981 Circle and Points单位圆覆盖
- 盒子模型补充知识汇总
- XDU-1139 猴子吃桃 II (水~斐波那契数列求和) From 西电校赛网络赛