5.Swift枚举|结构体|类|属性|方法|下标脚本|继承
1. 枚举:
->在Swift中依然适用整数来标示枚举值,需搭配case关键字
enum Celebrity{ case DongXie,XiDu,Nandi,BeiGai } // 从左到右对应0,1,2,3
enum CompassPoint {
case North
case South
case East
case West
//enum中可以定义方法
func show(){
print(self)
}
}
//定义enum 变量
var p = CompassPoint.North
var p2 = CompassPoint.South
p.show()
p2.show()
var point:CompassPoint = .West
switch point{
case .North:
print("北")
case .South:
print("南")
case .East:
print("东")
case .West:
print("西")
}
enum Week:Int {
case Sun, Mon, Tur, Wen, Thu, Fri, Sat
}
//原始的(裸值)需要进行类型标注,
// notice:这里通过调用枚举类型 Week 调用 枚举成员Sun 裸值(及C中所述的枚举整型值),需要在赋值的变量后面加上的的类型标示符号
var weekDay:Int = Week.Sun.rawValue
//也可以直接通过Week的 rawValue方法调用得道当前的 枚举成员
var week:Week? = Week(rawValue:7) //这里如果rawValue 超出了枚举值的返回,则返回为空,所以week需要使用可选值来接收
//还可以利用元组特性设置关联的枚举成员
enum BarCode {
case UIPCA(Int,Int,Int) //条形码
case QRCode(String) //二维码
}
//定义个枚举变量
var barcode = BarCode.UPCA(690,3322323,2)
barcode = Bar.QRCode("http://fdsafdsfa.com")
switch barcode {
case BarCode.UPCA(let(num,id,check)):
print("这是一个条形码 \(num)-\(id)-\(check)")
case BarCode.QRCode(let string):
print("这是一个二维码 对应的字符串是:\(string)")
}
}
/**使用新的写法,在绑定变量的同时,指定条件判断,类似于SQL*/
switch aPoint {
//在绑定一个变量的同时,可以绑定x == y
case let(x,y) where x == y:
print("x 与 y相等斜线上 x = y")
case let(x,y) where x == -y:
print("x 与 -y斜线上 x = -y")
default:
print("other")
}
2. 结构体和类:
相同点:
结构题和类,都在定义一种类型
都可以在内部定义属性和方法
都可以定义下标运算符
都可以定义初始化方法(Int 初试化器, 构造器 构造方法)
都可以使用扩展现有的功能(OC中有分类,Swift中没有分类,叫扩展)
都可以遵循制定的协议
不同点:
类可以继承,结构体不能
类有多态,结构体没有
类的内存支持自动引用技术,结构体不支持引用技术,结构体变量都是在栈中分配内存空间,不需要手动管理
类是引用类型 结构体是值类型
//属性的初始化就提供了一个无参 和统一的初始化器
struct Resolution {
var width = 0.0
var height:Float = 0.0
}
//类中申明属性必须进行初始化,除非它是可选值
class VideoMode {
var resolution = Resolution()
var interlocaed = false
var frameRate = 0.0
var name:String?
}
//结构体是值类 类是引用类型
var res = Resolution()
var res2 = res
res.width = 1024
res2.width
var vmode = VideoMode()
var vmode2 = vmode
vmode.name = "zhanshang"
vmode2.name
/** ===比较地址是否相等*/
if vmode === vmode2 {
print("两个引用是同一个值")
}
if vmode2 !== vmode {
print("两个引用不是同一个地址")
}
/** 结构体的统一初始化器,这与C中的结构题嵌套非常相识,紧紧是指把变量的定义方式改变了一下,另外支持 点语法访问层级嵌套属性*/
struct Point {
var x :Float
var y :Float
}
struct Size {
var w :Float
var h :Float
}
struct Rect {
var origin: Point
var size: Size
}
var rect = Rect(origin: Point(x: 100, y:20), size: Size(w : 2 ,h: 3))
rect.size.w
rect.origin.x
3. 属性,在Swift中属性有两个分类方式
第一种方式:
/**
1. Swift中属性有两个分类方式
第一种方式:
-> 存储属性(Stored Properties):用变量或者常量来保存属性值
-> 计算属性(calculate Properties): 通过计算得来的。
举例:
出生日期: 存储树形 , 年龄:需要通过两个时间进行计算
-> 第二中分类方式:
实例属性 和 类型属性
*/
// 存储属性
struct MyRange {
var location:Int
let length:Int
}
var myRnage = MyRange(location: 0, length:100)
struct Point {
var x = 0.0, y = 0.0
}
struct Size {
var w = 0.0, h = 0.0
}
struct Rect {
//存储属性,使用变量或者常量来保存存储属性
var orign = Point() //创建 point对象
var size = Size()
var center: Point {
get{
let centerX = orign.x + size.w * 0.5
let centerY = orign.y + size.h * 0.5
return Point(x: centerX, y: centerY) //返回一个point类型
}
//这里如果没有参数 则使用默认的 newValue
set{
let newOrignX = newValue.x - size.w * 0.5
let newOrignY = newValue.y - size.h * 0.5
orign = Point(x: newOrignX, y: newOrignY) //实现origin的赋值
}
/* set(newCenter){
let newOriginX = newCenter.x - size.w * 0.5
let newOriginY = newCenter.y - size.h * 0.5
origin = Point(x: newOriginX, y: newOriginY)
} */
//假设做一个只读的计算属性
}
//如果只读计算属性,只有一行代码可以省略return
var center2:Point {
get {
return Point(x: 500 + 100,y: 100)
}
}
}
var rect = Rect(orign:Point(x: 0, y: 0), size: Size(w:300,h: 200))
rect.center.x
rect.center.y
rect.center = Point(x: 200, y: 200)
rect.orign.x
rect.orign.y
/** 延迟属性 类似 OC的懒加载,或者延迟加载*/
class DataImporter {
init(){
print("DataImporter create")
}
var fileName = "data.txt"
//这个需要用到的时候才去加载
}
class DataManager {
lazy var dataImporter = DataImporter()
}
//创建DataManager这个对象
var dataManager = DataManager()
/**在需要执行懒加载的属性前面加上layz*/
dataManager.dataImporter
4. 属性监视器:是一段代码,这段代码会在属性发生变化的时候自动调用
->计算属性,延迟属性,不能设置监视器,只有存存储属性才能设置监视器
->属性监视器,在属性初始化的时候不调用
->属性监视器有两种,willSet,didSet
class StepCounter {
var labelText = " text content"
/**storeage property*/
var a :Int = 10
//只读计算属性
var b:Int {
return 10
}
// 给属性 加属性监视器
var totalSteps:Int = 10 {
willSet (newValue){
print("属性将要变化时调用 要改变成\(newValue) 现在是\(totalSteps)")
}
didSet{
print("属性值已经发生改变了嗲用原来的值时\(oldValue)现在是\(totalSteps)")
labelText = "改变的值时\(totalSteps)"
}
}
}
var propertyName:Int = 10{ willSet(newValue){ //inserCode here } didSet{ //insertCode here } }
var stepCounter = StepCounter()
stepCounter.totalSteps = 50
stepCounter.labelText
stepCounter.totalSteps = 20
stepCounter.labelText
5. 类型属性:
在结构体或者枚举中,使用static修饰的属性以及在类中使用class关键字修饰的属性叫做类型属性,属于整个类和对象无关。
在struct 中定义的类型属性,可以是存储属性,也可以是计算属性
在class 中定义的类型属性,只能是计算属性(如果需要使用存储树形座位设计类型属性,可以加上static关键字)
struct SomeStrut {
//存储属性
var a = 10
//计算属性
var b:Int {
return 10
}
//类型属性
static var x = 10
static var y:Int {
return 10
}
}
var someStruct1 = SomeStrut()
someStruct1.a //10
var someStruct2 = SomeStrut()
someStruct2.a //10
SomeStrut.x //10
SomeStrut.y //10
class SomeClass {
var a = 10
var b :Int {
return 10
}
/** 类型属性,太奇葩了*/
static var y :Int {
return 100
}
class var x:Int {
return 100
}
static var storeagePorperty:Int = 10 //编译通过。优先使用static
// Swift编译无法通过❌class var storagePorperty1:Int = 100
}
SomeClass.y
SomeClass.storeagePorperty = 123
SomeClass.x
6.实例方法,类方法,几乎同OC一样
//实例方法 与类方法,类中的实例方法几乎和OC一样
/** 类类型的实例方法*/
class Counter{
var count = 0
func increment(){
count++
}
func incrementBy(amount: Int){
count += amount
}
func incrementBy(amount: Int ,numberOffTimes: Int) {
count += amount * numberOffTimes
}
}
/** create a instance */
var counter = Counter()
/** invoke instance method*/
counter.increment()
/** 值类型的实例方法 */
struct Point {
var x = 10, y = 10 //实例 值类型属性,由对象调用,或者对象 self指针调用
var z = 250
static var sx = 10 //类类型属性,由类调用,或者类 self指针调用
func show() {
print("点点\(x)")
Point.sx = 1111
}
//值类型的实例方法,默认不可以修改实例属性,如果非要修改则加上mutating
mutating func setX(px: Int,AndY y:Int) {
// x = px
self.x = px
//防止参数和属性重名
self.y = y
Point.sx = 111
}
}
enum StatusSwitch{
case Study,Dining,Review,Sleep
func show(){
switch self{
case .Study:
print("正在学习")
case .Dining:
print("正在吃饭")
case .Review:
print("正在复习")
case .Sleep:
print("正在睡觉")
}
}
/** 切换状态, 这里如果想修改self需要在前面加上 mutating*/
mutating func nextStatus(){
switch self {
case .Study:
print("下一步吃饭")
self = .Dining
case .Dining:
print("下一步 去复习")
self = .Review
case .Review:
print("下一步 去睡觉")
self = .Sleep
case .Sleep:
print("下一步 去学习")
self = .Study
}
}
}
var ss = StatusSwitch.Study
ss.show()
ss.nextStatus()
ss.nextStatus()
ss.nextStatus()
ss.nextStatus()
ss.nextStatus()
ss.nextStatus()
ss.nextStatus()
ss.nextStatus()
7. 类型方法:
//类型方法 和 OC中的类方法,含义相同
class SomeClass {
var prop:Int = 0 //实例属性必须要有了对象之后能方位
class var a:Int { //类属性 ,class也可以使用static
return 10
}
func instanceMethod() {
print("this is a instance method")
self.prop
SomeClass.a
//self.a a为类属性,所以无法调用
}
class func typeMethod(){ // class func 代表定义个类方法
print("这是一个类型方法")
//同OC,类方法中不能访问实例属性,但是可以访问类型属性
// self.prop
self.a //self带表调用这个方法的对象,self相当于调用类方法的对象,类对象
SomeClass.a
}
}
var p = SomeClass()
p.prop
SomeClass.a
//类方法的调用
SomeClass.typeMethod()
//先创建一个类的对象-》
var instanceObject = SomeClass() //类名+()可以创建一个类的对象
instanceObject.prop
instanceObject.prop = 10
instanceObject.prop
struct SomeStruct {
var prop:Int = 0
/**声明一个static的存储属性*/
static var a: Int = 0
func show(){}
func instanceMethod(){
//此处实例属性可以读但是不能修改 prop = 1000,如果需修改采用
self.show()
print(prop)
}
/**结构体中, 类方法使用static,在类中可以使用static和class定义类方法和变量方法, C++里面叫做静态方法,但是在结构体中只能是static */
static func typeMethod(){
print("这是一个类型方法")
//self.show() 实例方法,❌,此处无法使用
}
}
/**枚举中 类型方法*/
enum StatusSwitch {
case Study,Dinig,Review,Sleep
static func typeMethod() {
print("这是一个类型方法")
}
static func create()->StatusSwitch {
return self.Study //StatusSwitch 类对调用 create 类方法,self 指向StatusSwitch,所以返回为StatusSwitch类型
}
func show() {
print("这是一个实例方法")
}
}
StatusSwitch.create().show() //
StatusSwitch.Study.show() //与上面等价 //枚举成员可以调用枚举类的方法,这样理解会好记一点,搞不明白的就暂时当成一种格式来记,等代码积累量上去了再回过头来研究。
8. 下标脚本,主要用于检查数组边界是否越界;使用断言的方式
class MyArray {
//private 私有的,越界返回真,不越界返回假
pravate var array = [0,1,2,3,4,5,6,7,8,9]
func indexIsValid(index:Int) -Bool {
if index < 0 || index >array.count - 1 { return ture } else { return false }
/**增加数据*/
func addObjectAtIndex(index:Int ,object:Int) {
assert(indexIsValid(index))
array.insert(object,atIndex:Index)
}
func show(){ print(array) }
}
//让MyArray支持下标,写法一
定义一个 通过subscript构建一个整型的下标函数,创建set 和 get方法,其中set方法中newValue和数组赋值时,外界传入的形参
subscript(index:Int)->Int {
get { return array[index] }
set { array[index] = newValue }
}
方法二:通过改写set方法
subscript(index:Double)->Int {
get{ return array[Int(index + 0.5)]}
set{ array[Int(index + 0.5)] = newValue }
//此处的newValue为set方法调用时外部带的参数 类似于 (int)setnewValue:(int)newValue
}
var myArray = MyArray()
myArray.show()
myArray.addObjectAtIndex(1, object: 100)
myArray.show()
myArray.array + [30,300]
myArray.array.removeAtIndex(5)
myArray.show()
myArray.array[0]
9. 继承:
父类 子类 (基类,派生类)
Swift中的特点: 一个类可以没有父类,不像OC所有的类都继承于NSObject,Swift中是单即成类,一个类只能由一个父类,但是可以有多个子类。
class Vehicle {
//存储属性 storage properties
var currentSpeed = 0.0
//计算属性 calculate properties
var description:String {
return "当前速度是每小时\(currentSpeed)公里"
}
func makeNoise() {
print("父类发生的方法")
}
func show(){
print("父类显示的方法")
}
}
/** inheritance*/
class Bicycle: Vehicle {
/** extension propertie*/
var hasBasket = false
/** extension method*/
func test(){
print("subClass extension method")
}
/** override parent method*/
override func makeNoise() {
print("subClass dong dong ...")
}
}
var bike = Bicycle()
bike.show()
bike.makeNoise()
bike.hasBasket
bike.currentSpeed
/**父类型指向子类型,前面obj为交通对象,makeNoise重写后被覆盖,先调用子类的方法
*/
var obj:Vehicle = Bicycle()
obj.makeNoise()
}
/**
覆盖父类的方法只需要在方法前面使用override关键字, override func 。。。。
重写父类属性只需要在子类定义与父类相同的属性,并在后面加上{ didSet{ //inertCode 需要重写的内容 } }
在父类中 变量和方法前面只要加上 final关键字则表示该方法不能被重写
*/
class Car : Vehicle{
var gear = 1
// 重写覆盖父类的方法
override func makeNoise(){
print("汽车滴滴")
}
// 重写计算属性
override var description : String {
return super.description + "在\(gear)档上"
}
// 重写父类的存储属性
override var currentSpeed : Double{
didSet{
gear = Int(currentSpeed/10.0) + 1
}
}
}
var car = Car()
car.gear
car.currentSpeed = 40
car.description
car.gear
/*final */ class Base { // 限制这个类不能被继承
final var a = 10 // final 不能被重写
final func show(){ } //final 的方法不能被重写
}
class Child: Base {
}
// 开发中还有一种常见的形式 组合
class Radio{
var price : Double = 0.0
func radio(){
print("收听广播")
}
}
class MyCar{
var radio = Radio()
}
var mc = MyCar()
mc.radio.radio()
mc.radio.price = 10000000
5.Swift枚举|结构体|类|属性|方法|下标脚本|继承的更多相关文章
- Swift枚举|结构体|类|属性|方法|下标脚本|继承
1. 枚举: ->在Swift中依然适用整数来标示枚举值,需搭配case关键字 enum Celebrity{ case DongXie,XiDu,Nandi,BeiGai } // 从左 ...
- 枚举类 enum,结构体类 struct
1.枚举类型的值,直观易于理解,见词知意. 格式: enum 枚举类名:值类型 { 值1, 值2, 值n } 每个值默认(省略“:值类型”)以int型数据存储,从0开始. 使用格式:枚举类名 变量=枚 ...
- 初学swift笔记 结构体(八)
import Foundation /* 和类很相似 结构体 -> 封装 属性.方法 结构体是值类型 */ //定义一个LSQ类型的结构体 关键字struct struct LSQ { var ...
- C#学习笔记_12_枚举&结构体
12_枚举&结构体 枚举 是一种数据类型 适用于某些取值范围有限的数据 语法: [访问权限修饰符] enum 枚举名 { 枚举值 } 枚举名遵循大驼峰命名法 枚举一般情况下是和switch c ...
- go语言进阶之为结构体类型添加方法
1.为结构体类型添加方法 示例: package main import "fmt" type Person struct { name string //名字 sex byte ...
- Swift----函数 、 闭包 、 枚举 、 类和结构体 、 属性
1 数组排序 1.1 问题 本案例实现一个整型数组排序的函数,数组排序的规则由传递的规则函数决定. 1.2 方案 首先定义一个整型数组排序函数sortInts,该函数有一个整型数组类型的参数,该参数必 ...
- Swift,结构体与类
1.结构体(小的类就是用struct来写) struct arrow{ var x=0,y=0 } 2.类(常用) class a{ var a=10 var b=20 } var b=a() //实 ...
- Swift Struct 结构体
前言 Swift 语言有两种基本的数据类型,即类(class)和结构体(struct),class 这样的概念大家不会陌生,而 struct 也并不是什么新的概念,在 Objective-C 和 C ...
- Swift 分类 结构体
感谢原作者:http://www.cocoachina.com/newbie/basic/2014/0612/8780.html 类和结构体是人们构建代码所用的一种通用且灵活的构造体.为了在类和结构体 ...
随机推荐
- iOS XCode启用/关闭Clang Warnings
前言:warnings是编码中很重要的一个环节,编译器给出合理的warning能帮助开发者找到自己代码的问题,防止很多bug产生. 默认用XCode创建一个工程,会自动开启一些重要的warnings ...
- .NET 串口通信中断接收,包含0X1A(作为EOF)
.NET串口通信中将`0X1A`当做EOF处理,.NET接收到EOF会触发一次接收中断,此时事件形参`SerialDataReceivedEventArgs`值为枚举 `Eof`,其他为`Chars` ...
- python---基础之模块,列表,元组,字典
1. 模块 写模块的时候尽量不要和系统自带的模块的名字相同 调用模块的时候,会先在当前目录下查找是否有这个模块,然后再会如python的环境变量中查找 a.模块1:sys 代码如下: import ...
- 初识Redis(1)
Redis 是一款依据BSD开源协议发行的高性能Key-Value存储系统(cache and store). 它通常被称为数据结构服务器,因为值(value)可以是 字符串(String), 哈希( ...
- linux----------ab--性能测试工具
ab.exe –n 10000 –c 100 localhost/index.php //其中-n代表请求数,-c代表并发数
- 接口测试(二)—HttpClient
使用HttpClient进行接口测试,所需要使用的相关代码 HttpClient进行接口测试所需jar包:httpclient.jar.httpcore.jar.commons-logging.jar ...
- Js动态获取iframe子页面的高度////////////////////////zzzz
Js动态获取iframe子页面的高度 Js动态获取iframe子页面的高度总结 问题的缘由 产品有个评论列表引用的是个iframe,高度不固定于是引发这个总结. 方法1:父级页面获取子级页面的高度 ...
- Oracle 多行变一列的方法
多行变一列的方法有很多,觉得这个第一眼看懂了当时就用的这个办法. 情况是这样的.以下数据前几列是一样的,需要把VAT_VALUE_CHAR 的值放在同一行上. SELECT * FROM ps_vat ...
- final review 报告
项目名:约跑 组名:nice! 组长:李权 组员:刘芳芳于淼韩媛媛 宫丽君 final Review会议 时间:2016.12.2 代码git的地址:https://git.coding.net/m ...
- C++文件流类与文件流对象
文件流是以外存文件为输入输出对象的数据流.输出文件流是从内存流向外存文件的数据,输入文件流是从外存文件流向内存的数据.每一个文件流都有一个内存缓冲区与之对应. 请区分文件流与文件的概念,不用误以为文件 ...