视频:P25-32 日期:4.29/4.30
目录
P27:类中使用属性计算,属性观察,下标语法(前面已介绍过)
P25:下标语法subscript
通过下标索引来获得值
import UIKit
//下标语法subscript
struct Person
{
private var array:[String] = ["swift","ios","macos"]
subscript(index:Int) -> String
{
set(new_value)
{
print("\(index) - " + new_value)
}
get
{
return "apple"
}
}
}
var person = Person()
person[100] = "hello" //通过下标语法传参数并且赋值
person[12345] = "12345"
print(person[12345])
/*
100 - hello
12345 - 12345
apple
*/
同时传入Int和String类型的参数
import UIKit
struct Person
{
private var array:[String] = ["swift","ios","macos"]
subscript(index:Int,param:String) -> String
{
set(new_value)
{
array.insert(new_value, at: index) //插入值
}
get
{
return array[index]+ " " + param
}
}
}
var person = Person()
person[0,"a"] = "hello"
print(person[0,"b"])
print(person[1,"c"])
/*
hello b
swift c
*/
P26:类的定义使用,类的实例是传引用
1.定义和使用
convenience init(){}
convenience:便利,使用convenience修饰的构造函数叫做便利构造函数
便利构造函数通常用在对系统的类进行构造函数的扩充时使用。
便利构造函数的特点:
1、便利构造函数通常都是写在extension里面
2、便利函数init前面需要加载convenience
3、在便利构造函数中需要明确的调用self.init()
//类的定义
import UIKit
class Student
{
//私有变量
private var name:String = "xiaoming"
private var age:Int = 18
private var score:Double = 60
private var ispass:Bool = false
//静态常量
public static let schoolName = "家里蹲大学"
//加convenience关键字的初始化器,无参数
convenience init()
//Designated initializer for 'Student' cannot delegate (with 'self.init'); did you mean this to be a convenience initializer? 不加convenience就报错啦
{
self.init(name: "xiaohong",age: 19, score : 90)
}
//带参数的初始化器
init(name:String,age:Int,score:Double)
{
self.name = name
self.age = age
isPass(param:score)
}
//私有函数isPass(),传入score参数
private func isPass(param:Double)
{
self.score = param
if self.score < 60
{
self.ispass = false
}
else
{
self.ispass = true
}
}
//公有函数
public func setScore(score:Double)
{
isPass(param: score) //将isPass()进行封装,不能直接修改isPass,只能通过setScore()来修改score
}
public func getName() -> String
{
return self.name
}
public func getAge() -> Int
{
return self.age
}
public func getScore() -> Double
{
return self.score
}
//静态函数,直接通过类名调用,不能通过实例调用
public static func get() -> String
{
return "swift"
}
}
var s1 = Student(name:"ZhangSan",age:20,score:59)
print("姓名 = " + s1.getName()) //使用结构体属性
print("年龄 = " + String(s1.getAge()))
print("分数 = " + String(s1.getScore()))
print(Student.get()) //get()静态函数,直接通过类名调用,不能通过实例调用
/*
姓名 = ZhangSan
年龄 = 20
分数 = 59.0
swift
*/
2.类的实例是引用
与结构体不同的是
1.类在传递递时候,传的是同一个对象,是引用不是值传递
import UIKit
class Student
{
var name = "hello"
}
var s1 = Student()
print(s1.name)
var s2 = s1 //指向同一个对象
print(s2.name)
s2.name = "world"
print(s1.name,s2.name)
/*
hello
hello
world world
*/
2.类在定义let实例的时候,仍然可以改变实例的var属性,但不能改变实例的let属性
import UIKit
class Student
{
var name = "hello"
}
let s1 = Student()
s1.name = "world"
print(s1.name)
/*
world
*/
否则报错,如下:
/*
import UIKit
class Student
{
let name = "hello"
}
let s1 = Student()
s1.name = "world"
print(s1.name)
*/
//报错
//Cannot assign to property: 'name' is a 'let' constant/
P27:类中使用属性计算,属性观察,下标语法(前面已介绍过)
1.属性计算、属性观察
import UIKit
class Person
{
private var value:String = "value"
var name:String
{
set
{
value = newValue
print("set - " + newValue)
}
get
{
return "get - " + value
}
}
var age:Int = -1
{
willSet
{
print("newValue = " + String(newValue))
}
didSet
{
print("oldValue = " + String(oldValue))
}
}
}
var person = Person()
person.name = "hello"
print(person.name)
person.age = 18
/*
set - hello
get - hello
newValue = 18
oldValue = -1
*/
2.下标语法
import UIKit
class Data
{
private var array1:[String] = ["Apple","Google"]
private var array2:[String] = ["android","ios"]
//使用下标
//可以使用多个参数
subscript(index1:Int, index2:Int) -> String
{
//用不上set所以没有写
get
{
return array1[index1] + "-" + array2[index2]
}
}
}
var data = Data()
print(data[0,1])
print(data[1,0])
/*
Apple-ios
Google-android
*/
P28:Any和AnyObject类型
import UIKit
//Any 和 AnyObject
//Any可以表示任何一个类型,包括class类型,但AnyObject只能表示class类型
class Person
{
var name:String
init(name:String)
{
self.name = name
}
}
struct Data
{
var data:String
init(data:String)
{
self.data = data
}
}
var a:Any = 1
print(type(of: a))
var b:Any = true
print(type(of: b))
var c:Any = "123"
print(type(of: c))
var cls:Any = Person(name:"class可以是Any类型")
var strc:Any = Person(name:"struct也可以是Any类型")
//没有报错
//var f:AnyObject = Data(name:"struct类型不能是AnyObject类型)
//Missing argument for parameter 'data' in call
//只能是类的类型
var k:AnyObject = Person(name:"只有class类型是AnyObject类型")
//不会报错
/*
Int
Bool
String
*/
P29:类的继承
//类的继承
import UIKit
//定义一个父类
class Person
{
private var name:String
private var age:Int
init(name:String,age:Int)
{
self.name = name
self.age = age
}
public func setName(name:String)
{
self.name = name
}
public func setAge(age:Int)
{
self.age = age
}
public func getName() -> String
{
return self.name
}
public func getAge() -> Int
{
return self.age
}
}
//如何继承Person()类:
class Student:Person //写法就是子类 冒号:父类
{
func play(param:String) //子类自己的新方法
{
print(param)
}
}
//创建父类实例per
var per = Person(name: "person", age: 10)
print(per.getName())
print(per.getAge())
per.setAge(age: 100)
print(per.getAge())
print("----------------------")
//创建子类实例stu
var stu = Student(name:"student",age:18)
//stu的功能都继承自Person
print(stu.getName())
print(stu.getAge())
print(stu.play(param: "student play"))
/*
person
10
100
----------------------
student
18
student play
*/
P30:向下类型转换(P29课的代码延续)
//向下类型转换
import UIKit
var student:Person = Student(name:"student",age:18)
print(student.getAge()) //没有问题,因为这个getAge()在父类中有
//这样定义student完全没有问题,因为Student类是Person的子类
var student2:Any = Student(name:"student",age:18)
//print(student2.getAge()) //有问题,因为这个getAge()在Any中没有
//报错Error:Value of type 'Any' has no member 'getAge'
//is 测试,在Java中是IS-A测试哈哈哈
print(student is Student)
print(student is Person)
print("------------------------")
//向下类型转换,可选类型问题
var s = student as? Student
//print(s.getAge())
//报错Error Value of optional type 'Student?' must be unwrapped to refer to member 'getAge' of wrapped base type 'Student'
//因为不知道s能不能转换为Stude类型
//1 因此如果明确知道可以转成Student类型,那就直接解析:
var s2 = student as! Student
print(s2.getAge())
//不会报错了
print("------------------------")
//2 若不明确是否能转成Studen类型:法一
var s3 = student as? Student
print(s3?.getAge())
print(s3!.getName())
print("------------------------")
//3 若不明确是否能转成Studen类型:法二-可选项绑定
if let s4 = student as? Student
{
print(s4.getAge())
print(s4.getName())
}
/*
student
18
student play
----------------------
18
true
true
------------------------
18
------------------------
Optional(18)
student
------------------------
18
student
*/
P31:方法重载
import UIKit
//class Student0
//{
// func play(param:String)
// {
// print(param)
// }
// func play(param:String)
// {
// print(param)
// }
//}
//报错Error
//若有两个方法的名称参数完全一样,则会报错,因此必须使之至少一个不一样,
//比如参数不一样
class Student1
{
func play(param:String)
{
print(param)
}
func play(param:Int)
{
print(param)
}
}
//参数个数不一样
class Student2
{
func play(param:String,param2:Int)
{
print(param)
}
func play(param:String)
{
print(param)
}
}
//多个参数顺序不一样
class Student3
{
func play(param:String,param2:Int)
{
print(param)
}
func play(param2:Int,param:String)
{
print(param)
}
}
//参数名称不一样
class Student4
{
func play(param:String)
{
print(param)
}
func play(param2:String)
{
print(param)
}
}
//返回类型不一样
class Student5
{
func play(param:String) -> String
{
return ""
}
func play(param:String) -> Int
{
return 123
}
}
P32:重写方法,final禁止继承重写
//重写需要改变量范围,open>public>internal>fileprivate>private
private的范围太窄,需要扩大范围,其中internal是默认的选项,如果不写默认就是internal
//重写的时候需要用override关键词进行变量或者函数重写
// 有setter需要有getter,但有getter不一定要有setter-Variable with a setter must also have a getter
// 以前的父类的方法该是什么就是什么,子类就是要override,进行改变
//32 -重写
import UIKit
//定义一个父类
class Person
{ //重写需要改变量范围,open>public>internal>fileprivate>private
var name:String
private var age:Int
init(name:String,age:Int)
{
self.name = name
self.age = age
}
public func setName(name:String)
{
self.name = name
}
public func setAge(age:Int)
{
self.age = age
}
public func getName() -> String
{
return self.name + "person"
}
public func getAge() -> Int
{
return self.age
}
}
//如何继承Person()类:
class Student:Person //写法就是子类 冒号:父类
{
override var name:String
{
set
{
super.name = super.name + " set student"
}
get
{
return super.name + " get student"
}
}
override init(name: String, age: Int)
{
super.init(name: name, age: age)
self.name = name
}
}
var per = Person(name:"xiaoming",age : 18)
print(per.name)
var stu = Student(name:"xiaohong",age:16)
print(stu.name)
/*
xiaoming
xiaohong set student get student
*/
//重写函数
class Student:Person //写法就是子类 冒号:父类
{
override init(name: String, age: Int)
{
super.init(name: name, age: age)
self.name = name
}
override func getName() -> String
{
return super.getName() + " - student"
}
}
var stu = Student(name:"xiaohong",age:16)
print(stu.getName())
stu.setName(name: "setname")
print(stu.getName())
/*
xiaohongperson - student
setnameperson - student
*/
//final 禁止继承重写
final class Person
{
}
否则会报错:Inheritance from a final class 'Person'