swift学习笔记7
七、面向对象
swift可以定义
面向对象类型: 枚举 结构体 类 ,可以定义变量,枚举,结构体是值类型,类定义变量是引用类型
以上三种都支持定义存储属性,计算属性,方法,下标,构造器,嵌套类型。
JAVA支持的特性,swift都支持,不支持的,它也支持,语法简洁,但功能并不简单,反而很强大!
OOP :Object Oriented Programming 以对象为中心编程
对象总有状态和行为,对应的:
属性:描述对象的状态
方法:描述对象的行为
面向对象两大核心:类和对象
类:具有共同特征的对象的定义,如 人类, 对象是类的具体实例,你,我,乔布斯,雷蛋蛋
面向对象典型三大特征:
封装: 把对象的状态数据,实现细节隐藏起来,只露出合适的方法,允许外部程序调用,改变程序状态。 private ,internal public 限制封装
继承:复用已有的类,一般到特殊,苹果继承了水果,单继承,通过协议来弥补不足
多态:
swift 的 类 结构体 枚举 具有完全平等的地位
5种面向对象程序单元为:类,结构体,枚举,扩展,协议
注意:实例和对象不同
实例:结构体和枚举的实例
对象:类的实例
复杂的是:swift 中 类,结构体,枚举的内部分别可以定义属性(存储属性和计算属性),方法,下标,构造器,嵌套类型(嵌套类,嵌套结构体,嵌套枚举) 这5种类型成员!
真是让人 要疯了~
只有类支持继承
人之为学有难易乎?为之,则难者亦易矣,不为,则易者亦难矣!
枚举:管理一组有限的值的集合 enum 名字首字母大写,连续驼峰命名法
比如季节 性别
不同的是:成员不会默认分配一个整数值
enum Weekday
{
case Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday
}
调用
var chooseDay = Weekday.Saturday
switch(chooseDay)
{
case .Monday:
println("星期一")
case .Tuesday:
。。。类似 省略
}
原始值:可以使 Int ,Double,Float,Character,String 类型的值
enum Weekday :Int
{
case Monday,Tuesday = 1,Wednesday=5,Thursday,Friday,Saturday,Sunday
}
enum Season :Character
{
case Spring = "S"
。。。
}
属性:rawValue 获取指定枚举值的原始值
var day = Weekday.Saturday
day.rawValue //8
关联值:associated value
类似属性,为每个枚举值定义更多的数据,从而更好地描述该枚举代表的实例的状态。
enum Planet
{
case Mercury(weight:Doubel,density:Double,name:String)
case Earth(Double,String)
}
调用
var p1 = Planet.Mercury(weight:0.05,density:5.43,name:"水星")
类 官方说,主要是使用类
private internal public final
类定义,最常用的 构造器,属性,方法
构造器:构造该类的实例
属性:定义该类或该类的实例所包含的状态数据
方法:定义该类或该类的实例的行为特征或者功能实现
类名后边()表示调用 构造器,从而返回该类的实例
计算属性:实例变量
存储属性:保存类型本身或实例的状态数据
构造器 init 不能声明返回值类型 无需写return
class Person
{
//定义存储属性
var name:String = ""
var age:Int = 0
//定义方法
func say(content:String)
{
println(content)
}
}
// 创建实例
var p:Person
// 调用构造器
p = Person()
//上边两句 简写 成
var p = Person()
// 实例的作用
1、访问实例属性
2、调用实例的方法
p.name = "renhairui"
p.say("swift是一门非常强大的语言")
大多数情况,定义一个类,就是为了重复创建类的实例,类是多个实例的共同特征
假如用上边的例子创建 结构体
struct Person
{
//定义存储属性
var name:String
var age:Int
//定义方法
func say(content:String)
{
println(content)
}
}
则
var my = Person(name:"renhairui",age:28)
println(my.name) // renhairui
假如调用无参数的构造器创建实例
var hello = Person()
则 hello.age 是0
引用类型比较 === !==
比较两个引用类型的变量是否指向同一个实例
只有引用类型的变量才能用 这个!
self关键字 指向该方法的调用者
实例方法中:self代表 调用该方法的实例
类型方法中:self代表代用该方法的类型(类或者结构体)
class Dog
{
func jump()
{
}
func run()
{
self.jump() //允许实例的成员调用另一个成员,可以省略self jump()正确!
}
}
在方法中强制引用存储属性 用self
class wolf
{
var name :String = ""
var age:Int = 2
init (name:String,age:Int)
{
self.name = name
self.age = age
}
func info ()
{
println("我的名字是\(name),年龄是\(age)岁")
}
}
调用
var wolf = Wolf(name:"任海瑞",age:28)
wolf.info()
self 作为方法调用者时,可以访问self,甚至当成返回值
class ReturnSelf
{
var age:Int = 0
func grow()->ReturnSelf
{
age ++
return self
}
}
调用
var rt = ReturnSelf()
rt.grow()
.grow()
println(rt.age)
结构体:封装少量相关的简单数据值,该实例在赋值和传递时会自动复制副本
存储属性: 1定义是指定初始值,2构造器中定义初始值
延迟存储 第一次被调用是才会被计算初始值的属性,lazy
lazy load 当某个实例持有另一个创建成本比较大的实例的引用时,降低内存开销,提升程序性能。
class Dept
{
var id:Int
var info:String
init (id:Int)
{
self.id = id
NSThread.sleepForTimeInterval(2)// 模拟耗时操作
self.info = "模拟读取数据库"
}
}
class User
{
var id:Int = 0
// 这个时候如果调用 Dept 则会创建较大成本实例 不能用 var dept = Dept(id :20)
lazy var dept = Dept(id:20)
var nicks = [String]()
}
//创建实例
var user =User()
user.nicks.append("孙悟空")
user.nicks.append("任海瑞")
println(user.nicks)
计算属性:本质是 getter setter方法的组合
class User
{
var first:String = ""
var last:String = ""
var fullName:String
{
// 定义计算属性的getter方法 返回值由first,last两个存储属性决定
return first +"-"+last
}
set(newValue){
// 改变first last两个存储属性
var names = newValue.componentsSeparatedBystring("-") //字符串切割成数组
self.first = names[0]
self.last = names[1]
}
}
init(first:String,last:String)
{
self.first =first
self.last = last
}
调用
let s = User(first:"海瑞",last:"任")
println(s.fullName) // 海瑞-任
s.fullName = "悟空-孙"
println(s.first) //悟空
println(s.last) //孙
setter方法提供隐式参数名 newValue 不用写 直接用
set {
var names = newValue.componentsSeparatedBystring("-") //字符串切割成数组
self.first = names[0]
self.last = names[1]
}
不写setter方法 就是只读的计算属性
属性观察者 willSet() didSet()
方法:行为特征的抽象
函数:放在枚举,结构体,类以外定义
方法:上边三种内定义,枚举,结构体中用static,类中用class,意思一样
类型.方法
实例.方法
class SomeClass
{
func test(){ //方法}
class func bar(#msg:String)
{
println("bar类型方法,传入参数:\(msg)")
}
}
用
var sc = SomeClass()
//sc的test分离成函数 注意:千万不能加(),否则变成方法调用,不是将方法赋值给函数类型的变量
var f1:()->() = sc.test
var f2:(String)->Void = SomeClass.bar
// 下面两个一样
sc.test() f1()
SomeClass.bar(msg:"测试信息") f2("测试信息")
注意:结构体,枚举的实例方法不能分离,转换成函数,他们的类型方法才可以。
默认为方法除第一个参数外的其他形参都添加了外部形参名,不用写外部参数名或者#了,比较人性化。
enum,stuct,class中的func是实例方法
命名习惯:
方法名,以动词开头,动词+名词(描述第一个参数的含义)
有时候还会在动词和名词之间 加 with,for ,by介词,尽力把调用方法像一条简单的英文句子
func indexOfObject()
可变方法
结构体和枚举都是值类型,默认情况下,实例方法不能改变实例的存储属性。
假如需要修改,则mutating 声明为可变方法,可以在方法体内对隐式的self重新赋值
作用:改变枚举,结构体的内部数据。
struct Rect
{
var x:Int
var y:Int
var width:Int
var height:Int
mutating func moveByx(x:Int,y:Int)
{
self.x += x
self.y += y
}
}
// 创建实例
var rect = Rect(x:20,y:12,width:200,height:300)
// 调用可变方法
rect.moveByx(100,y:80)
println("\(rect.x),\(rect.y)")
下标:可以访问 对象,结婚,序列(枚举,结构体,类都支持)
P175
swift学习笔记7的更多相关文章
- 【swift学习笔记】二.页面转跳数据回传
上一篇我们介绍了页面转跳:[swift学习笔记]一.页面转跳的条件判断和传值 这一篇说一下如何把数据回传回父页面,如下图所示,这个例子很简单,只是把传过去的数据加上了"回传"两个字 ...
- Swift学习笔记(一)搭配环境以及代码运行成功
原文:Swift学习笔记(一)搭配环境以及代码运行成功 1.Swift是啥? 百度去!度娘告诉你它是苹果最新推出的编程语言,比c,c++,objc要高效简单.能够开发ios,mac相关的app哦!是苹 ...
- swift学习笔记5——其它部分(自动引用计数、错误处理、泛型...)
之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...
- swift学习笔记4——扩展、协议
之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...
- swift学习笔记3——类、结构体、枚举
之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...
- swift学习笔记2——函数、闭包
之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...
- swift学习笔记1——基础部分
之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...
- Swift学习笔记一
最近计划把Swift语言系统学习一下,然后将MagViewer用这种新语言重构一次,并且优化一下,这里记录一下Swift的学习笔记. Swift和Objective-C相比,在语法和书写形式上做了很多 ...
- 记录:swift学习笔记1-2
swift还在不断的更新做细微的调整,都说早起的鸟儿有虫吃,那么我们早点出发吧,趁着国内绝大多数的coder们还没有开始大范围普遍应用. 网上有些大神说:swift很简单!我不同意这个观点,假如你用h ...
- Swift学习笔记(14)--方法
1.分类 方法分为实例方法和类型方法 实例方法(Instance Methods):与java中的类似,略 类型方法(Type Methods):与java.oc中的类方法类似.声明类的类型方法,在方 ...
随机推荐
- 线程中t.setdaemon(), t.jion(), t.start的使用
import threading import time def f0(): pass def f1(a1,a2): time.sleep(10) f0() ") t1 = threadin ...
- route-显示并设置Linux内核中的网络路由表
route命令 网络配置 route命令用来显示并设置Linux内核中的网络路由表,route命令设置的路由主要是静态路由.要实现两个不同的子网之间的通信,需要一台连接两个网络的路由器,或者同时位于两 ...
- service使用handler与Activity沟通的两种方法
通过之前的学习,我们知道了在主线程中声明一个handler实例并实现了消息的处理方法之后,我可以在子线程中用此实例向主线程发消息,在处理方法中获取消息并更新UI. 那么,如果我们想用handler在s ...
- DBVisualizer Pro for mac
公司使用的是DB2数据库,支持DB2的数据库客户端常用的有DBeaver和DBVisualizer.DBeaver是免费的,但本人电脑安装后,启动一直报错,问题一直没解决就放弃了.改用DBVisual ...
- Hadoop中Partition的定制
1.解析Partition Map的结果,会通过partition分发到Reducer上,Reducer做完Reduce操作后,通过OutputFormat,进行输出,下面我们就来分析参与这个过程的类 ...
- Sublime Text 3下安装Emmet的问题
电脑装了Sublime Text 3,顺便安装了很多插件,今天编写前端HTML代码时,想用起前端常用的Emmet插件的功能,Emmet插件已经安装好了,奈何输入简写格式,按“CTRL+E”,没有反应. ...
- invalid loc header的解决办法
eclipse 运行程序,报invalid loc header,网上一查,删除maven仓库(默认位于%USERPROFILE%\.m2\repository\org)中的下载包,然后重新下载.
- python接口自动化(三十六)-封装与调用--流程类接口关联续集(详解)
简介 上一篇已经给大家都介绍过了流程类接口关联,但是由于博客的登录机制改变,所以没有办法给小伙伴们实战演练一下,那么这篇就按照上一篇计划的用jenkins来给小伙伴们演示一下流程类接口的封装和调用,其 ...
- scrapy-redis源码解读之发送POST请求
1 引言 这段时间在研究美团爬虫,用的是scrapy-redis分布式爬虫框架,奈何scrapy-redis与scrapy框架不同,默认只发送GET请求,换句话说,不能直接发送POST请求,而美团的数 ...
- Spark Streaming 官网上提到的几点调优
总的来说,需要考虑以下两点: 1. 有效地运用集群资源去减少每个批次处理的时间 2. 正确的设置batch size,以使得处理速度能跟上接收速度 一. 为了减少处理时间,主要有以下几个优化点: 1 ...