在开始介绍Swift中的扩展之前,我们先来回忆一下OC中的扩展。

在OC中如果我们想对一个类进行功能的扩充,我们会怎么做呢。

对于面向对象编程的话,首先会想到继承,但是继承有两个问题。

第一个问题:继承的前提是这个类可以被继承,在Swift中又不可以被继承的类 final,OC中也有不可以被继承的类

第二个问题:继承是侵入性的,就是我们可能只是想实现一个功能,但是继承之后,子类就会把父类的所有功能(属性和方法)都继承了,这个代价太大。

所以OC给我们提供了一种很强大的解决方式,使用类别扩展。

NSString+Extension.h

#import <Foundation/Foundation.h>

@interface NSString (Extension)

- (BOOL)validateEmial;

- (NSInteger)intValue;

@end

NSString+Extension.m

#import "NSString+Extension.h"

@implementation NSString (Extension)

- (BOOL)validateEmial {
NSRange range = [self rangeOfString:@"@"];
if (range.location == NSNotFound) {
return NO;
}else {
return YES;
}
}
//当类别中出现了已有的方法,会覆盖原有的实现方法。
- (NSInteger)intValue {
NSLog(@"intValue");
return ;
} @end

这里我们就定义了一个类目,下面来解释一下:

类别文件的定义格式:"需要添加类别的类名+类别的名称"

上面是OC中为一些类添加新的功能。那么在Swift中我们应该怎么做呢。其实Swift为我们提供了一个关键字 extension 来表明为一个类进行扩展。

代码示例:

//为String扩展功能
extension String {
func validateEmial() -> Bool {
let rang = self.range(of: "@")
if (rang != nil) {
return false
}else {
return true
}
}
}
//使用
let str1 = "@123"
if str1.validateEmial() {
print("为真")
}else {
print("为假")
}

扩展计算型的属性(扩展属性是有局限性的 只能扩展计算型属性)

虽然不能扩展存储型属性 但是我们可以在自己扩展的计算型属性中改变存储型属性

extension Double {
var KM:Double{
return self * 1000.0
}
var m: Double { return self }
var cm: Double { return self / 100.0 }
}
let oneInch = 24.5.KM//

也可以在扩展中扩展新的构造函数,但是这个构造函数必须是便利构造函数。

struct Point {
var x = 0.0
var y = 0.0
} struct Size {
var width = 0.0
var height = 0.0
} class Rectangle {
var origin = Point()
var size = Size()
init(origin:Point,size:Size) {
self.origin = origin
self.size = size
}
} //扩展
extension Rectangle {
func translate(x:Double,y:Double) {
self.origin.x += x
self.origin.y += y
}
}
let rect = Rectangle(origin: Point(), size: Size(width: , height: ))
//调用扩展方法
rect.translate(x: , y: ) extension Rectangle {
var center:Point {
get {
return Point(x: origin.x + size.width / , y: origin.y + size.height / )
}
set(newCenter) {
//存储型属性可以在扩展的计算型属性中被修改
origin.x = newCenter.x - size.width/
origin.y = newCenter.y - size.height/
}
}
//扩展构造器
convenience init(center:Point,size:Size) {
let originx = center.x - size.width /
let originy = center.y - size.height /
self.init(origin:Point(x: originx, y: originy),size:size)
}
}

内嵌类型

class UI {
//UI类型的内嵌类型
enum Theme {
case DayModel
case NightModel
} var fontColor: UIColor!
var backgroundColor: UIColor!
var themeModel:Theme = .DayModel {
didSet {
self.changeModel(themeModel: themeModel)
}
} init() {
self.themeModel = .DayModel
self.changeModel(themeModel: self.themeModel)
}
func changeModel(themeModel:Theme){
switch themeModel {
case .DayModel:
self.fontColor = UIColor.white
self.backgroundColor = UIColor.black
default:
self.fontColor = UIColor.black
self.backgroundColor = UIColor.white
}
}
}
let ui = UI()
ui.themeModel//类型UI.Theme

扩展内嵌类型

extension Rectangle {
enum Vertex {
case LeftTop
case RightTop
case RightBottom
case LeftBottom
}
func pointAtVertex(v:Vertex) -> Point {
switch v {
case .LeftTop:
return origin
case .RightTop:
return Point(x: origin.x + size.width, y: origin.y)
case .RightBottom:
return Point(x: origin.x + size.width, y: origin.y + size.height)
default:
return Point(x: origin.x, y: origin.y + size.height)
}
}
}

扩展标准库

extension Int {
var square:Int { return self * self
}
var cube:Int {
return self * self * self
}
func inRange(closeLeft:Int,openEndRight:Int)->Bool {
return self >= closeLeft && self < openEndRight
}
//封装一个重复若干次的动作
func repetitions(task:()->()) {
for _ in ..<self {
task()
}
} }
let index =
index.inRange(closeLeft: , openEndRight: ) index.repetitions {
print("重复的逻辑")
}

泛型

//<T>定义的一个泛型 可以是任何类型
func swapTwoThings<T>( a:inout T,b:inout T) {
(a,b) = (b,a)
} var tian = "hahahaha"
var lian = "heiheihei"
swapTwoThings(a: &tian, b: &lian) var a =
var b =
swapTwoThings(a: &a, b: &b)

泛型类型

把泛型应用到某种类型中就是泛型类型例如:arr:Array<Int> = Array<Int>()就是一个泛型类型。

//栈 可以存储任何类型的数据 所以我们可以使用泛型 本质为数组
struct Stack<T> {
var items = [T]()
func isEmpty() ->Bool {
return items.count ==
}
mutating func push(item:T) {
items.append(item)
}
mutating func pop() ->T? {
guard !self.isEmpty() else {
return nil
}
return items.removeLast()
}
}
//查看栈顶元素
extension Stack {
func top() -> T? {
return items.last
}
} var s = Stack<Int>()
s.push(item: )
s.push(item: )
s.pop()
var ss = Stack<String>() struct Pair <T1,T2> {
var a:T1
var b:T2
} var pair = Pair<Int,String>(a:,b:"hello")

Swift 学习笔记(扩展和泛型)的更多相关文章

  1. 【swift学习笔记】二.页面转跳数据回传

    上一篇我们介绍了页面转跳:[swift学习笔记]一.页面转跳的条件判断和传值 这一篇说一下如何把数据回传回父页面,如下图所示,这个例子很简单,只是把传过去的数据加上了"回传"两个字 ...

  2. Swift学习笔记(一)搭配环境以及代码运行成功

    原文:Swift学习笔记(一)搭配环境以及代码运行成功 1.Swift是啥? 百度去!度娘告诉你它是苹果最新推出的编程语言,比c,c++,objc要高效简单.能够开发ios,mac相关的app哦!是苹 ...

  3. Typescript 学习笔记七:泛型

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  4. swift学习笔记5——其它部分(自动引用计数、错误处理、泛型...)

    之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...

  5. swift学习笔记4——扩展、协议

    之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...

  6. swift学习笔记之-扩展(Extensions)

    //扩展(Extensions) import UIKit /*扩展(Extensions):扩展 就是为一个已有的类.结构体.枚举类型或者协议类型添加新功能.这包括在没有权限获取原始源代码的情况下扩 ...

  7. Swift 学习笔记十五:扩展

    扩展就是向一个已有的类.结构体或枚举类型加入新功能(functionality).扩展和 Objective-C 中的分类(categories)相似.(只是与Objective-C不同的是,Swif ...

  8. swift学习笔记1——基础部分

    之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...

  9. swift学习笔记3——类、结构体、枚举

    之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...

随机推荐

  1. chrome禁用JS

    有一些网站不允许文本选择,对于我这种伸手党实在是很不友好.当然像这类的功能,应该是用JS来控制. chrome的话,JS禁用可以在地址栏旁边的一个下拉列表那里选.

  2. Timeout watchdog using a standby thread

    http://codereview.stackexchange.com/questions/84697/timeout-watchdog-using-a-standby-thread he simpl ...

  3. 【ActiveMQ】管理界面查看消息详情,报错/WEB-INF/tags/form/forEachMapEntry.tag PWC6199: Generated servlet error: The type java.util.Map$Entry cannot be resolved. It is indirectly referenced from required .class files

    ActiveMQ版本:5.12 JDK版本:1.8 ===================== 使用ActiveMQ过程中,在管理界面查看消息详情,发现报错: 查看日志信息,报错如下: 2017-11 ...

  4. android windowSoftInputMode属性详解(转)

    activity主窗口与软键盘的交互模式,可以用来避免输入法面板遮挡问题,Android1.5后的一个新特性. 这个属性能影响两件事情: [一]当有焦点产生时,软键盘是隐藏还是显示 [二]是否减少活动 ...

  5. Android性能优化第(三)篇---MAT比Menmery Monitor更强大

    作者 LooperJing 2016.11.17 16:42* 字数 1687 阅读 1603评论 3喜欢 21 在Android性能优化第(一)篇---基本概念中讲了JAVA的四大引用,讲了一下GC ...

  6. hdu1017(C++)

    这个题目很水,但是卡了格式和m=0的情况,wa了好多次,题目只给出N=1,感觉没说清楚 #include<iostream>using namespace std;int main(){ ...

  7. http各类攻击及tcpcopy工具

    1.专业的还得ixia.Spirent TestCenter等软硬件一体的 2.一般的使用软件的,安装在linux上使用 参考: 1.http://blog.csdn.net/wuzhimang/ar ...

  8. Git的提交忽略文件

    .gitingore文件内容如下 /target//.settings//.classpath/.project/logs/

  9. poj1270Following Orders(拓扑排序+dfs回溯)

    题目链接: 啊哈哈.点我点我 题意是: 第一列给出全部的字母数,第二列给出一些先后顺序. 然后按字典序最小的方式输出全部的可能性.. . 思路: 整体来说是拓扑排序.可是又非常多细节要考虑.首先要按字 ...

  10. ext tree展开时的一些技巧

    加入子节点的时候.我们须要展开父节点.并选中刚加入好的节点. 这时候会有一个问题. 我用的ext-js-4.2起码有一种问题. 节点内部会混乱.要么多加一个. 要么层级会发生故障. 随后我发现一个窍门 ...