安安IOSiOSiOS深度报告

Swift 十二讲 第八章 类型扩展(Extensions)和协

2015-02-05  本文已影响136人  zydscience

1. Extensions

扩展指的是对已经有的类或者类型添加一些你自己定义的属性,方法。甚至对内建的类型也可以进行扩展。这显然极大的增强了这门语言的威力和灵活性。如下例:

extension Int
{
var a:String{
    return "你是个好人"
}
}


var b:Int=2
println(b) //输出2
println(b.a) //输出 "你是个好人"

实例方法的扩展,就是添加一个成员函数。这个成员函数和被创建的实例绑定。例如:

extension Int
{
func a()->String{
    return "你是"+String(self)+"个好人"
}
}


var b:Int=20
println(b) //输出20
println(b.a()) //输出“你是20个好人”

如果用mutating关键字,那么实例方法可以修改实例的值。例如:

extension Int
{
mutating func a()
{
    self = -self
}
}


var b = 1
println(b) //输出1
b.a()
println(b) //输出-1

类型方法的扩展,前面要加static之类的关键字。这是因为这个方法是和类的定义绑定在一起的。例如:

extension Int
{
static func a()
{
   println("坏蛋")
}
}


var b = 20
println(b)  //输出20
Int.a()    //输出"坏蛋"

你还可以给类型添加下标扩展,方便使用。下表扩展和方法扩展的写法非常类似。例如:

extension Int
{
subscript(i:Int)->Int
{
   println("下标扩展被调用")
   return 123
}
}


var b = 20
println(b[0]) //输出“下标扩展被调用”;输出 123
  1. Protocols

协议是一组属性,方法,下标等的声明的容器。当你定义一个类的时候,可以指明它需要遵从的协议,然后在类的内部,实现协议规定的那些东西。注意,协议只是个容器,不是实现。所以其实是比类更高一级的描述。描述的是多个类的共同特征。所以协议里的变量,只能声明,不能初始化。方法下标也是如此。例如

protocol a {
var ax:Int = 1
}  //Playgroudn会立即报错,"initial value is not allowed here"

了解了协议这个语法的设计思路。它的一些具体写法和用法就可以自然而然的理解了。

protocol 协议名
{//里面写你要定义的东西
}

class 类的名字:[上类的名字] 协议的名字,第二个协议的名字,..等等

如果一个类是从上类继承而来,那么要把上类的名字写在协议名字之前。一个类可以遵从多个协议。

protocol a {
func ax()-> Int

}

extension Int: a
{
func ax() -> Int {
    println("对不起,你是个好人")
    return 0
 }
}

var b = 1
b.ax() //输出: 对不起,你是个好人

由上例可以看出,协议是用于多个类的定义的。例如你很多类都要发好人卡,那么定义个协议就可以让你的代码组织结构更好。如果只是一个类需要这个好人卡函数,那就没必要使用协议。

面向对象的一些语言要素,到这一章就基本介绍完了。这里还牵涉到一个更大的话题。一般来说,面向对象的很多特点,例如类继承扩展协议等等都是为了更有组织的进行代码复用。但是,每多一层容器,代码的冗余部分也就越复杂,组织结构也就更复杂。那么,到底在设计项目的结构体系的时候,应不应该用面向对象特性呢?笔者的意见很简单:跟着常识走。如果一个对象或者过程,在现实世界中很容易被拟物,而且后面有很大机会被复用,那设计一个类往往是没错的。例如图形界面元素,按钮。按钮本身就是个物体,然后被图形界面拟物。按钮这个物体显然是有颜色,有大小,有被按后进行什么操作的功能的。所以你设计个类,就不会出错。因为每个程序员脑子里的按钮都是以现实经验为基础的,观念也就比较一致。

但是,例如一些商业逻辑,你采用面向对象的设计思路,就未必是个好办法。这是因为对商业逻辑的理解,人人都可能不同。想想看,买火车票排队这回事,实际上是多么的复杂。这种情况下,笔者认为,不要采用面向对象的方法。不然设计这个体系结构的人走了,你的项目基本就作废了。因为这种情况下设计出来的类协议等等,肯定是个人观点和视角的产物。而人与人之间的交流,往往比一般人想象的要困难的多。

很多计算机书,拿个什么电话号码本,什么矩形长宽,什么员工进出纪录之类的东西,来展示面向对象的方法多么有用,这实际上是不负责任的做法。没有考虑到复杂体系本身的计算开销和维护开销。只考虑了其效果。

当然,你要说我有的是钱。开个项目,写文档的也是第一流人才,或者文档的人比写代码的素质还高。那我就会推荐你用面向对象的元素多一些。

3. 附录,GIT为什么是纯C写的?


笔者认为,Linus的观点有些偏颇了。面向对象编程经过几千万人数不清程序验证过的场合,最牢靠的就是图形界面设计。为什么在这个领域这么牢靠?为什么今天图形用户界面部分的编程主流还是面向对象的?我认为主要原因就是图形界面都是拟物的。每个人的集体共识都差不多,所以不会出错。

From: Linus Torvalds <torvalds <at> linux-foundation.org>
Subject: Re: [RFC] Convert builin-mailinfo.c to use The Better String Library.
Newsgroups: gmane.comp.version-control.git
Date: 2007-09-06 17:50:28 GMT (2 years, 14 weeks, 16 hours and 36 minutes ago)

On Wed, 5 Sep 2007, Dmitry Kakurin wrote:

When I first looked at Git source code two things struck me as odd:

  1. Pure C as opposed to C++. No idea why. Please don't talk about portability,
    it's BS.

下面是Linus的回答:

YOU are full of bullshit.
C++ is a horrible language. It's made more horrible by the fact that a lot
of substandard programmers use it, to the point where it's much much
easier to generate total and utter crap with it. Quite frankly, even if
the choice of C were to do nothing but keep the C++ programmers out,
that in itself would be a huge reason to use C.
In other words: the choice of C is the only sane choice. I know Miles
Bader jokingly said "to piss you off", but it's actually true. I've come
to the conclusion that any programmer that would prefer the project to be
in C++ over C is likely a programmer that I really would prefer to piss
off, so that he doesn't come and screw up any project I'm involved with.
C++ leads to really really bad design choices. You invariably start using
the "nice" library features of the language like STL and Boost and other
total and utter crap, that may "help" you program, but causes:

Linus

上一篇下一篇

猜你喜欢

热点阅读