视频:P33-40 日期:5.1/5.2
目录
P33:属性计算观察和下标的继承和重写
1.继承下标
import UIKit
//继承下标
class Person
{
var array:[String] = ["swift","ios"]
subscript(index:Int) -> String
{
set
{
}
get
{
return array[index]
}
}
init()
{
}
}
class Student:Person
{
}
var student = Student()
print(student[0])
print(student[1])
/*
swift
ios
*/
2.重写下标
//重写下标
import UIKit
class Person
{
var array:[String] = ["swift","ios"]
subscript(index:Int) -> String
{
set
{
}
get
{
return array[index]
}
}
init()
{
}
}
class Student:Person
{
override subscript(index:Int) -> String
{
set
{
}
get
{
return "override - " + super[index]
}
}
}
var student = Student()
print(student[0])
print(student[1])
/*
override - swift
override - ios
*/
P34:多态调用方法和属性的问题
//在B继承A之后,定义变量时var s = B() 与 var s:A = B() 是不一样的。
//强制类型转换 var s1 = s as! B 就是把s1转换成B
import UIKit
class A
{
var name:String
init(name:String)
{
self.name = name
}
func printName()
{
print("this is A " + name)
}
}
class B:A
{
func play()
{
print("this is B play")
}
}
var s1 = A(name:"a")
print(s1.name)
s1.printName()
print()
var s2 = B(name: "b")
print(s2.name)
s2.printName()
s2.play()
print()
var s3:A = B(name: "b")
print(s3.name)
s3.printName()
//s3 没有play()
//s3 有printName(),因为在A里面找不到,在B里面也不会去找了
print()
//强制类型转换
var s4 = s3 as! B
s4.play() //强制s4类型转换成B类型之后,就有paly()方法了
/*
a
this is A a
b
this is A b
this is B play
b
this is A b
this is B play
*/
P35:类型判断处理,对象相等性判断
1.类型判断和处理
import UIKit
class A
{
}
var t1 = A()
var t2 = A()
print(t1 === t2)
//false
//因为类传递的是引用,t1和t2是两个不同的类
var t3 = t1
print(t1 === t3)
//true
//因为传递引用的都是t1在定义时的类的对象,t1和t3引用的是同一个对象
class A
{
}
class B:A
{
var name:String
init(name:String)
{
self.name = name //需要实例化否则会报错
}
func printName()
{
print("this is B name = " + self.name)
}
}
class C:A
{
var name:String
init(name:String)
{
self.name = name
}
func printName()
{
print("this is C name = " + self.name)
}
}
func getObject(param:Int) -> A
{
if (param>10)
{
return B(name: "小B")
}
else
{
return C(name: "小C")
}
}
//getObject 返回的是A类型
var obj = getObject(param: 15)
//obj.
//object没有什么.方法,因为A是空的
print(type(of: obj))
//B
//说明obj是A类型,被强制转换成B类型
2.对象相等性判断
//类型判断用is关键字
if (obj is B)
{
var p = obj as! B
p.printName()
}
else if(obj is C)
{
var p = obj as! C
p.printName()
}
//这是常见的向下类型转换的方式
if let t1 = obj as? B
{
t1.printName()
}
else if let t2 = obj as? C
{
t2.printName()
}
/*
this is B name = 小B
this is B name = 小B
*/
P36:扩展extension,泛型
1.扩展extension
//扩展extension,泛型
import UIKit
//扩展就是对现有的结构体进行结构和功能的扩展
//比如对下面已经定义好的类A,还想再加一些功能,就用extension
class A
{
}
extension A
{
var name:String{return "hello world"}
func toString()
{
print("this is A toString")
}
}
var a = A()
a.toString()
print(a.name)
//如果将toString定义为静态函数也,也可以直接用类名A.toString()
/*
this is A toString
hello world
*/
import UIKit
//也可以对现有类型进行扩展
extension String
{
func toString() -> String
{
return "长度 = " + String(self.count)
}
}
var s:String = "hello"
print(s.toString())
/*
长度 = 5
*/
2.泛型
import UIKit
//泛型
func toString<T>(param:T) ->T //类型是T,参数类型是T,返回T类型,T是一个不确定的类型
{
return param
}
print(toString(param: "hello")) //因此可以传入任意类型
print(toString(param: 1))
print(toString(param: 1.5))
print(toString(param: [1,2,3]))
/*
hello
1
1.5
[1, 2, 3]
*/
import UIKit
//数组泛型
var array:Array<Int> = [1,2,3]
print(array[2])
/*
3
*/
P37:协议protocol
//协议protocal,相当于API
import UIKit
//协议protocal,相当于API
class TestClass
{
}
protocol Protocal1
{
var value1:String{set get} //定义value这个String类型是可写、可读的
func play1() -> String //后面没有跟大括号,只是定义了这个函数
}
protocol Protocal2
{
var value2:String{get} //可读
func play2() -> String
}
class Data:TestClass,Protocal1,Protocal2 //这是一个实现类,用来实现接口
{
var value1:String
var value2:String{return "value2"} //相当于默认get
func play1() -> String
{
return self.value2
}
func play2() -> String
{
return self.value2
}
init(value1:String)
{
self.value1 = value1
}
}
var data = Data(value1:"hello")
print(data.play1())
print(data.play2())
/*
value2
value2
*/
P38:延迟属性lazy
//加lazy后一直没有被初始化,直到用的时候才初始化
import UIKit
class Data
{
init()
{
print("data init")
}
func play()
{
print("data play")
}
}
class Test
{
lazy var data:Data = Data() //加lazy后一直没有被初始化,直到用的时候才初始化
init()
{
print("Test init")
}
}
var test = Test()
test.data
test.data.play()
/*
Test init
data init
data play
*/
P39:普通初始化器,可失败初始化器
1.普通初始化器
import UIKit
var name:String
//普通初始化器
class Test
{
var name:String
init(name:String)
{
self.name = name
}
}
var t = Test(name:"hello")
print(t.name)
2.可失败初始化器
var name:String
//普通初始化器
class Test
{
var name:String
init ? (name:String)
{
if(name == "unknown")
{
return nil
}
self.name = name
}
}
var t:Test? = Test(name:"xiaoming")
if let p = t
{
print(p.name)
}
else
{
print("初始化失败")
}
/*
xiaoming
*/
P40:必要初始化器,结构体成员初始器,闭包设置属性值
1.必要初始化器
//必要初始化器required
class Test
{
var name:String
required init(name:String)
//required的意思就是如果有类继承这个类的话,就有必要实现一下这个初始化器
{
self.name = name
}
}
class T:Test
{
required init(name: String)
{
super.init(name:name)
//这步是最重要的需要实现的一步,要用super实现父类
//下面的步骤想干啥都行
}
}
var t = T(name: "hello")
print(t.name)
/*
hello
*/
2.结构体成员初始器
import UIKit
//结构体成员初始化器
struct Test
{
var name:String
var age:Int
// init(name:String,age:Int)
// {
// self.name = name
// self.age = age
// }
}
var t = Test(name:"hello",age:10)
print(t.name) //即,初始化器上面的部分是默认的的,有或没有都可以调用
print(t.age)
//但是类和结构体不一样,类一定要有初始化器
//因此如果在结构体里没有什么需要做的事情,完全可以把类变成初始化器
/*
hello
10
*/
3.闭包设置属性
//3.闭包设置属性
import UIKit
class Test
{
var name:String = {return "swift"}()
var age:Int = //闭包设置属性,也可以在初始化器里面设置
{
var a = 10
var b = 20
return a+b
}()
init(name:String,age:Int)
{
self.name = name
self.age = age
}
}
var t = Test(name:"xiaoming " ,age:100 )
print(t.name)
print(t.age)
/*
xiaoming
100
*/