Init
// *** Initialization ***
// * unlike object-C, initialization in swift does not return a value
// in it's simplest form, it is like a instance method with no parameter
// in init you sld put all un-declared parameters, options are default nil
struct Girl {
var Boobs:Character
var ismantype : String?// if you remove ? mark it will report error
var someThing: String = "this is something"
init(){
Boobs = "A"
}
init(Acup:Int){
Boobs = "B"
}
init(Bcup:Int){
Boobs = "C"
print("yeah daddy got B \(Bcup)")
}
init(_ Nocup: Int){
print("god damn it!")
Boobs = "G"
}
}
var bigDaddy = Girl(Bcup: 3)
var holyCrap = Girl(7)
struct ConstantPropExample {
let constantProp:String
init(){
constantProp="xxx"
}
init(constantProp:String){
self.constantProp=constantProp// becos parameter take precedence
}
}
var test1 = ConstantPropExample(constantProp: "kkk")
print(test1.constantProp)
// init delegation, differ from value types and ref types
// 1 value type
struct Point{
var x=0.0,y=0.0
}
struct Size{
var height=0.0,width=0.0
}
struct Rect{
var point = Point() // if not inited it will return error on init(){}
var size = Size()
init(){}
init(point:Point,size:Size){
self.point=point
self.size=size
}
init(centerPoint:Point,size:Size){
//error: self used before self.init call
//self.point.x = centerPoint.x - size.width/2
//self.point.y = centerPoint.y - size.height/2
//self.init(point : self.point,size : self.size)
let point_x = centerPoint.x - size.width/2
let point_y = centerPoint.y - size.height/2
self.init(point:Point(x: point_x, y: point_y),size:size)
}
}
// 2 ref type
// * designated(primary&mandatory) init * convenience init(secondary)
// 3 golden rules for class type initialize delegation
// rule 1 : a designated init must call a designated init from it's immediate supper class
// rule 2 : a convenient init must call another init from the same class
// rule 3 : a convenient init must eventually call a designated init
// simple way to remember
// designated must delegate up, convenient must delegate across
// 2 phase init
// first phase assign value & determine init state
// second phase can have chance to customize it's property then ready it
// such desing avoids property been accessed before inited, also prevents unexpected value setting with another init
// safty check for 2 phase mechaniqes
// get parent ready-> child -> delegate -> convenient -> ready to use self/other functions
// init inheritance & overriding
class Car {
var wheel = 4
var desc : String {
return "I got \(wheel) wheels"
}
}
class SonCar:Car{
var soneToken = 3
override init(){
super.init()
// self.desc = "what the faak" // desc is a get only property
wheel = 2
}
init(Hey:Int){
soneToken = 4 // this is ok because it's it's own property
super.init()// why you have to put super.init() here
wheel = Hey
}
}
class Food {
var name : String
/*
init(){
name = "no name"
}
*/
init(name:String){
self.name = name
}
convenience init(){
//self.init() //this became a endless loop
self.init(name:"somefood")
}
}
var someFood = Food()
print(someFood.name)
class Ingredient:Food{
var quantity:Int
init(name:String,quantity:Int){
self.quantity = quantity
super.init(name:name)
}
/* override init(name:String){
self.quantity = 1 // must put before super.init
super.init(name:name)
}
*/
// convenience init(){
// self.init(name:"somexxx")
// }
override convenience init(name:String){
self.init(name:name,quantity:1)
}
}
var someTest = Ingredient()// it still can call it's parent conv init()
print(someTest.quantity)
class Purchased:Ingredient{
var hasBought = false
var desc : String {
var string = "\(quantity) -> \(name) has been bought:"
string += hasBought ? "right" : "wrong"
return string
}
}
var buytest = Purchased()
print(buytest.desc)
buytest.hasBought = true
print(buytest.desc)
var shoppingList = [
Purchased(),
Purchased(name:"egg",quantity:15),
Purchased(name:"bread")
]
for i in shoppingList{
print(i.desc)
}
// failable init can return nil
class FailTest {
var desc:String
init?(){
return nil
}
init?(name:String){
if name == "big"{return nil}
desc = name
}
}
// failable for enum
enum Temperature{
case A,B,C
init?(desc:String){
switch desc {
case "damn it":
self = .A
default:
return nil
}
}
}