//继承
//语法
/* 修饰符 class SubClass : SuperClass { //类定义部分 } */
class Fruit {
var weight = 0.0
func info()
{
println("我是一个水果,重\(weight)")
}
}
//定义Fruit类的子类Apple
class Apple : Fruit {
var name : String!
func taste()
{
println("\(name)吃起来很好吃")
}
}
//使用该实例
var a = Apple()
a.weight = 56
a.name = "红富士"
a.info()//我是一个水果,重56.0
a.taste()//红富士吃起来很好吃
//重写父类的方法
class Bird {
func fly()
{
println("我在天空里自由自在的飞翔。。。")
}
}
class Ostrich : Bird {
//override 方法重写,同名方法覆盖
override func fly() {
println("我只能在地上跑")
}
}
var o = Ostrich()
o.fly()//我只能在地上跑
//重写父类的属性
//重写父类的属性时一样需要使用override修饰符
class Bird1 {
var speed : Double = 0
}
class Ostrich1 : Bird1 {
//重写bird1的属性
override var speed : Double {
get {
println("正在访问被重写的属性")
return super.speed
}
set {
super.speed = newValue * newValue
}
}
}
//创建Ostich1实例
var os = Ostrich1()
os.speed = 20.0
println(os.speed)//400.0
//重写属性观察者
//父类还是Bird1
class Ostrich2 : Bird1 {
//重写Bird类的speed属性,添加属性观察者
override var speed : Double {
didSet{
//属性值改变后,会自动执行该方法
super.speed *= speed
}
}
}
var os1 = Ostrich2()
os1.speed = 20.0
println(os1.speed)//400.0
/*swift 不允许在子类中定义与父类中同名的存储属性 */
//重写父类的下标
//下面的例子中父类有一个只读下标,重写之后添加了set方法,变成读写属性
class Base {
subscript (idx : Int) -> Int {
get {
println("父类的下标的get方法")
return idx + 10
}
}
}
class Sub: Base {
//重写Base下标
override subscript(idx : Int) ->Int {
get{
println("重写后的get下标")
println("通过super访问被重写之前的下标:\(super[idx])")
return idx * idx
}
set {
println("重写后的下标的setter方法传入的参数\(newValue)")
}
}
}
var base = Base()
println(base[7])//17
var sub = Sub()
println(sub[7])//49
//类的构造与析构
//类的指定构造器和便利构造器
/* 便利构造器前要加converience convenience init (形参){ } */
//Apple1类使用便利构造器实现构造器的重载
class Apple1 {
var name : String!
var weight : Double
//定义指定构造器
init(name: String,weight: Double)
{
self.name = name
self.weight = weight
}
//便利构造器,使用convenience修饰
convenience init(n name: String,w weight: Double)
{
//便利构造器必须调用一个类中得其他构造器
self.init(name:name,weight:weight)
self.name = name
}
}
var app1 = Apple1(n: "junjun",w: 12)
println(app1.name)
var app2 = Apple1(name: "yuyu",weight: 13)
println(app2.name)
//两段式构造
class Fruit1 {
var name : String
init(name: String)
{
self.name = name
}
}
class Apple5: Fruit1 {
var color : String
init (color: String)
{
// println(self.color)//初始化之前不可使用本类定义的实例存储属性。编译报错
//必须先初始化当前类定义的存储属性
self.color = color
//可以访问当前类定义的实例存储属性
println(self.color)
//重新赋值
self.color = "红色"
// println(super.name)//不可使用父类定义的实例存储属性。编译错误
super.init(name: "红花果")
//可以访问父类定义的实例存储属性
println(super.name)
super.name = "红富士"
}
}
var aa = Apple5(color: "绿色")
println(aa.name)
//使用is运算符检查类型
//声明一个被Objective-C类使用的协议
@objc protocol TextProtocol{}
//声明hello时使用NSObject类,侧hello的编译时类型是NSObejct
//hello变量的实际类型是NNString
let hello : NSObject = "hello"
println("hello 是String \(hello is Nsstring)")//hello 是String true
//字符串是否是NSDate类型
println("hello 是 NSDate \(hello is NSDate)")//hello 是 NSDate false
//Any和AnyObject
//AnyObject:可代表任何的实例
//Any:可代表任何的类型。包括Int,Double等类型。
var anyArray : [Any] = ["swift",29,["any":90],"JiangJun"]
//遍历数组元素为Anyde 数组
for element in anyArray {
if element is Nsstring{
println(element)
}
}
//定义元素类型为AnyObject的数组,该数组的元素只能是对象
var anyObjectArray : [AnyObject] = [Apple5(color: "红色"),Apple5(color: "蓝色")]
//嵌套类型
//扩展
/* 修饰符可以省略,也可以是private|internal|public [修饰符]extension 已有类型 { //添加新的功能 } 扩展协议 [修饰符] extension 已有类型 : 协议1,协议2 { //实现方法 } */
//使用扩展不能添加实例存储属性,下面使用扩展来增加String的功能
extension String
{
//通过扩展增加类型存储属性
static var data : [String:Any] = [:]
//定义一个计算属性。并添加getter,setter方法部分
var length: Int {
get{
return count(self)
}
set{
var originLength = count(self)
//如果新设置的长度大于字符串原来长度,侧在字符串后面添加空字符
if newValue > originLength {
for idx in 1...originLength {
self += ""
}
}
//如果新设置的长度小于字符串原有的长度,侧将后面多余的字符截断
else if newValue < originLength
{
var tmp = ""
var count = 0
for ch in self
{
tmp = "\(tmp) \(ch)"
count++
//如果已经拼接了newValue个字符,则跳出循环
if count == newValue{
break
}
}
self = tmp
}
}
}
}
String.data["swift"] = 89
String.data["OC"] = 92
println(String.data)
var s = "fkit,org"
println(s.length)
s.length = 5
println(s)//f k i t,
s.length = 20
println(s)//f k i t,后面还有15个空格
*/
///
extension String
{
//添加一个新方法,用于获取当前字符串中指定中指定的范围的字符串
func subsrtingFromStrart(start : Int,toEnd : Int) -> String
{
var count = 0
var tmp = ""
for ch in self
{
//从start开始获取字符
if count >= start
{
tmp = "\(tmp)\(ch)"
}
//获取到toEnd处结束,程序不再需要后面的字符
if count >= toEnd - 1
{
break
}
count++
}
return tmp
}
//定义一个类方法,该类方法用于将bool值转换为字符串
static func valueOf(value : Bool) -> String {
return "\(value)"
}
}
var str = "fkit.orgisagoodcenter"
//截取原字符串中索引为5开始,到索引为10之间的子串
var subStr = str.subsrtingFromStrart(5,toEnd: 10)
println(subStr)//orgis
println(String.valueOf(true));//true
//添加可变方法,类不可以定义可变方法,
//下面方法用于计算当前数组与另一个数组的交集
extension Array
{
//定义一个方法,用于计算数组的交集
mutating func retainAll(array : [T],compartor : (T,T) -> Bool)
{
var tmp = [T]()
//遍历当前数组中所有元素
for ele in self
{
//遍历第二个数组的所有的元素
for target in array
{
//如果两个元素通过compartor比较返回true
if compartor(ele,target)
{
tmp.append(ele)
break
}
}
}
self = tmp
}
}
var books = ["ios","Android","swift","Java","Rudy"]
books.retainAll(["Android","xuexi"]){
return $0 == $1
}
println(books)//[Android,swift]
//使用扩展添加构造器
//定义一个结构体不包含任何构造器,系统将为之提供1个默认的构造器
struct SomeStruct
{
var name : String
var count : Int
}
//使用扩展来添加构造器
extension SomeStruct
{
//通过扩展添加的2个构造器对该类型原有的构造器没有影响
init(name:String)
{
self.name = name
self.count = 0
}
init(count:Int)
{
self.count = count
self.name = ""
}
}
//下面使用了SomeStruct的3个构造器,其中第一个构造器是系统提供的
var sc1 = SomeStruct(name: "fkit",count: 3)
var sc2 = SomeStruct(name: "JiangJun")
var sc3 = SomeStruct(count: 5)
//使用扩展添加嵌套类型
//下面为String添加枚举
extension String
{
//定义一个嵌套枚举
enum Suit : String
{
case Diamond = "♦️"
case Clud = "♣️"
case Heart = "❤️"
}
//通过扩展为String添加一个类型方法,用于判断指定字符串属于那种花色
static func judgeSuit(s: String) -> Suit?
{
switch(s)
{
case "♦️":
return .Diamond
case "♣️":
return .Clud
case "❤️":
return .Heart
default:
return nil
}
}
}
//使用String包含的嵌套枚举
var s1: String.Suit? = String.judgeSuit("❤️")
println(s1)//Optional((Enum Value))
var s2: String.Suit? = String.judgeSuit("j")
println(s2)//输出nil
//协议
/* 语法格式 修饰符:private, internal, public [修饰符] protocol 协议名 : 父协议1,父协议2... { //协议内容 } 2.实现协议 struct 结构体名:FirstProtocol,AnotherProtocol,... { //实现协议要求 } 3.类不仅可以实现多个协议,还可以实现协议时继承一个父类,此时需要把所有的父类放在协议之前 class 类名:SuperClass,FirstProtocol,... { //实现协议要求 } 4.协议指定的属性要求 [class ] var 属性名:类型{get [set]} class:可有可无,有说明要求定义类型属性;无说明定义的是实例属性。此处不可使用staic代替class 此处只要get,set即可无须提供实现,其中set可有可无,如果有set侧要求该实现者必须提供与之匹配的读写属性;如果没有set,侧只要求该实现者提供与之匹配的只读属性 */
//描边属性,画笔的粗细
protocol Strokable
{
var strokeWidth : Double{get set}
}
//填充颜色,定义一个枚举作为协议属性的类型,由于协议并不支持嵌套类型,因此程序只能将枚举定义在协议之外
protocol Fullable
{
var fullColor : Color? {get set}
}
enum Color
{
case Red,Green,Blue,Yellow,Cyan
}
//定义一个协议,并让该协议实现两个父协议
protocol HasArea : Fullable,Strokable
{
var area : Double {get}
}
//下面定义一个协议,该协议包含两个类型属性要求,协议中得类型属性使用class关键字修饰
protocol Mathable
{
static var pi: Double {get}
static var e: Double {get}
}
//让Rect实现两个协议
struct Rect: HasArea,Mathable
{
var width: Double
var height: Double
init(width:Double,height:Double)
{
self.width = width
self.height = height
}
//使用存储属性实现Fullable协议的fullColor属性
var fullColor: Color?
var strokeWidth: Double = 0.0
var area: Double {
get{
return width * height
}
}
//通过存储属性实现Mathable协议要求的两个类型属性
//虽然协议中使用class关键字定义类型属性,但值类型中依然使用static定义类型属性
static var pi: Double = 3.14159535
static var e: Double = 2.71828
}
//下面定义一个Circle类,该类同样实现了。上面的HasArea和Mathable两个协议
class Circle: HasArea,Mathable
{
var radius:Double
init (radius:Double)
{
self.radius = radius
}
//使用存储属性实现Fullable协议的Fullcolor属性
var fullColor:Color?
//使用存储属性实现HasArea协议的strokeWidth属性
var strokeWidth:Double = 0.0
//使用存储属性实现HasArea协议要求的area属性
var area: Double {
get{
return Circle.pi * radius * radius
}
}
//通过存储属性实现Mathable协议要求的两个类型属性
//由于类不支持定义类型存储属性,只能使用类型计算属性
class var pi:Double {return 3.14159535}
class var e:Double {return 2.71828}
}
var rect = Rect(width: 4.5,height: 4.0)
println(rect.area)//18.0
rect.fullColor = Color.Red
rect.strokeWidth = 1.0
println(rect.fullColor)//Optional((Enum Value))
println(rect.strokeWidth)//1.0
var circle = Circle(radius: 2.0)
println(circle.area)
circle.fullColor = Color.Green
circle.strokeWidth = 0.5
//协议指定的方法要求
protocol Eatable
{
//定义实例方法
func taste()
static func test(msgs: String...)
}
//结构体实现Eatable协议
struct Pie : Eatable
{
var weight:Double
//定义实例方法
func taste() {
println("\(weight)斤饼干吃起来香脆可口")
}
//结构体使用static修饰类型方法
static func test(msgs: String...) {
println("饼干实现的test方法")
for msg in msgs
{
println("个数可变的形参:\(msg)")
}
}
}
//实现Eatable协议
class Apple1:Eatable
{
var name:String
init(name:String)
{
self.name = name
}
//定义实例方法
func taste() {
println("\(name)水分充足,营养丰富")
}
//类使用class修饰类型方法
class func test(msgs: String...) {
println("苹果实现的test方法")
for msg in msgs
{
println("个数可变的形参:\(msg)")
}
}
}
Pie.test("饼干1","饼干2","饼干3")
var pie = Pie(weight: 2.3)
pie.taste()
//调用形参个数可变的类型方法
Apple1.test("苹果1","苹果2","苹果3")
var apple = Apple1(name: "红富士")
apple.taste()
//协议指定的可变方法要求
//可变方法使用mutating修饰,类不存在可变方法,因此类是引用类型,类中的方法本来就可以改变实例数据,枚举,结构体来实现协议中得可变方法时,也需要使用mutating修饰;但使用类实现该协议中得可变方法时,侧无需使用mutating修饰
protocol Incrementable
{
//定义可变的实例方法
mutating func incrementByDelta(delta:Double)
}
//上面协议定义了一个mutating修饰的可变方法,这表明结构体既可使用可变方法来实现该方法,也可使用非可变方法来实现该方法
//实现Incrementable协议
struct FkRange:Incrementable
{
var start: Double
var length: Double
//实现协议中得可变方法,依然使用mutating修饰
mutating func incrementByDelta(delta: Double) {
self.length += delta
}
}
//实现Incremntable协议
class Circle1 : Incrementable
{
var radius: Double
init(radius:Double){
self.radius = radius
}
//实现协议中得可变方法,无须使用mutating修饰
func incrementByDelta(delta: Double) {
self.radius += delta
}
}
var range = FkRange(start: 2.0,length: 10.0)
range.incrementByDelta(5.0)
println(range.length)//15.0
var circle1 = Circle1(radius: 3.0)
circle1.incrementByDelta(5.0)
println(circle1.radius)//8.0
//协议指定的下标要求
//协议能要求实现者必须提供哪些下标,也能要求该下标是否有setter部分和getter部分
/* subscript(形参列表) -> 返回值 {get[set]} 此处只要写get,set即可,无须提供实现。其中set可有可无。如果有set,则要求实现者必须提供与之匹配的读写下标:如果没有set,则要求该实现者提供与之匹配的只读下标 */
protocol Mathable3
{
//定义两个重载的下标
subscript(idx:Int) -> Int {get}
subscript(a: Int,b: Int) -> Int {get}
}
//实现Mathable3协议
struct LinearStruct : Mathable3
{
var factor: Int
//提供getter,setter部分,使之成为读写下标
subscript(idx: Int) ->Int
{
get{
return factor * idx
}
set{
println("执行LinearStruct的下标赋值")
}
}
//实现只读下标
subscript(a: Int,b: Int) -> Int
{
return factor * a + b
}
}
//下面使用一个Quadratic类实现Mathable协议,也需要实现协议中得两个下标
class Quadratic: Mathable3
{
var factor : Int
init(factor: Int)
{
self.factor = factor
}
//实现下标
subscript(idx: Int) -> Int
{
return factor * factor * idx
}
//实现只读下标
subscript(a: Int,b: Int) -> Int
{
return factor * factor * a + b
}
}
var q = Quadratic(factor: 5)
println(q[4])//100
println(q[4,6])//106
var line = LinearStruct(factor: 5)
println(line[4])//20
println(line[4,6])//26
//协议指定的构造器要求
//使用类实现协议,并实现协议中得构造器时,必须使用required修饰该构造器,除非该类使用了final修饰(该类不能派生子类),此时可以省略构造器的required(也可不省略)
//使用类实现协议,并实现协议中得构造器时,如果该构造器,还重写了其父类的构造器,则必须同时使用required override修饰
protocol Initable
{
//定义两个必须被实现类所实现的协议
init(name: String)
init(name: String,weight: Double)
}
//实现Initable
struct Bag : Initable
{
var name: String
var weight: Double
//结构体实现协议的构造器没有太多要求
init(name: String)
{
self.name = name
self.weight = 0.0
}
init(name: String,weight: Double)
{
//调用同一个类中另外一个重载的构造器
self.init(name:name)
self.weight = weight
}
}
//定义一个Apple类来实现Initable协议
class Fruit1
{
var name: String
init(name: String)
{
self.name = name
}
}
//继承Fruit1
class Apple8 : Fruit1,Initable
{
var weight : Double
//重写父类方法。并实现协议中得构造器,因此需要使用override required修饰
override required init(name: String)
{
self.weight = 0.0
super.init(name: name)
}
//使用便利构造器实现协议中得构造器
required convenience init(name: String,weight: Double) {
self.init(name: name)
self.weight = weight
}
}
var ap1 = Apple8(name: "红富士")
var ap2 = Apple8(name: "无花果",weight: 2.3)
println("\(ap2.name),\(ap2.weight)")
var bag1 = Bag(name: "书包")
var bag2 = Bag(name: "旅行包",weight: 20)
println("\(bag2.name),\(bag1.name)")
//合成协议
//swift还允许将多个协议合成一个临时的类型,这种用法为合成协议,格式
//protocol<协议1,协议2,协议3,...>,必须同时实现合成协议的所有的协议
//使用合成协议来定义arg形参
func test1(arg: protocol<HasArea,Mathable3>)
{
/* 编译器知道arg参数必须是HasArea的实例类型的实例 因此arg参数有fullColor属性 */
println("arg的填充颜色是\(arg.fullColor)")
//因此arg参数有strokenWidth属性
println("arg的描边笔的粗细是\(arg.strokeWidth)")
println("arg参数的面积是\(arg.area)")
}
var circle5 = Circle(radius: 1.2)
circle5.strokeWidth = 0.5
circle5.fullColor = Color.Red
var rect5 = Rect(width: 3.4,height: 2.8)
rect5.strokeWidth = 0.8
rect5.fullColor = Color.Green
//
//test1(circle5)
//test1(rect5)
//通过扩展为已有的类型添加协议
//定义一个Eatable协议
protocol Eatable1
{
func taste()
}
//通过扩展让String实现Eatable1协议
extension String : Eatable1
{
//实现Eatable1协议中得方法
func taste() {
println("\(self)吃起来味道不错,呵呵")
}
}
func eat(foods : Eatable1...)
{
//遍历foods个数的参数,foods相当于数组
for food in foods
{
food.taste()
}
}
//调用eat()方法,并传人3个String作为Eatable实例
eat("swift","oc")
//唯类协议
//只支持被类实现,不允许被枚举,结构体实现,
//定义唯类协议在协议名后的冒号后面添加class关键字即可(class放在所有父协议的第一位)
/* protocol 协议名 : class,父协议1,... { //唯类协议的定义 } */
protocol Movable : class
{
func move()
}
class Car : Movable {
func move() {
println("汽车在飞")
}
}
var car1 = Car()
car1.move()
//可选协议,是唯类协议,必须添加@objc修饰
@objc protocol MyProtocol
{
//定义可选属性
optional var status : String {get}
//可选方法
optional func increment(val: Int)
//可选下标
optional subscript(idx: Int) -> Int{get}
}
//定义一个空类来实现协议
class EmptyClass : MyProtocol {
}
//选择性的实现MyProtocol协议
class MyClass : MyProtocol
{
var name : String
init(name : String)
{
self.name = name
}
//实现协议中得可选属性
var status : String
{
if count(name) < 10
{
return "良好"
}
else
{
return "超长"
}
}
//实现协议中得可选方法
func increment(val: Int) {
println("系统正在增长长度")
for idx in 1...val
{
name += "="
}
}
}
var mp : MyProtocol = MyClass(name: "JiangJun")
//访问属性
println(mp.status)
mp.increment?(10)
println(mp.status)
//输出实例和Printable协议
//下面定义了一个person类
class Person
{
var name : String
var age : Int
init(name: String,age : Int)
{
self.name = name
self.age = age
}
var description : String {
//返回一个字符串
return "name = \(self.name),age = \(age)"
}
}
var person = Person(name: "悟空",age: 500)
println(person)
println(person.description)
//使用自定义类型作为字典的key
//重载全局的==运算符
//class User0 : Equatable
//{
// var name : String
// var password : String
// var age : Int
// init(name: String,password : String,age : Int)
// {
// self.name = name
// self.password = password
// self.age = age
// }
//}