//类和结构体
//共同点:1.定义属性用于存储值 2.定义方法用于提供功能
//3.定义构造器用于生成初始化值 4.通过扩展以增加默认实现的功能
//5.实现协议以提供某种标准功能
 
//类的附加功能有:1.继承允许一个类继承另一个类的特征
//2.类型转换允许在运行时检查和解释一个类实例的类型
//3.允许一个类实例释放任何其所被分配的资源
//4.引用计数允许对一个类的多次引用
 Dlg{
var
var
    //var ddd = MyMode()
 }
class
var dlg = Dlg() //结构体Dlg的实例,
var interlaced =  false
var
var name : String?
 }
class
    var fileName = "data.txt"//假设这个类的初始化会消耗不少时间
 }
class
lazy var importer =  DataLoading()
var data = [String]()
 }
class ViewController:  UIViewController
     
override func
super.viewDidLoad()
//存储属性
         //简单来说,一个存储属性就是存储在特定类或结构体的实例里的一个常量或变量
         //存储属性可以是变量存储属性(var),也可以常量存储属性(let)
struct
var firstValue:  Int
let length:  Int
         }
var rangeOfThreeItems =  FixedLengthRange(firstValue: 0, length: 3) //  该区间表示整数0,1,2
firstValue
        //  该区间现在表示整数6,7,8
         
let rangeOfThreeItems2=FixedLengthRange(firstValue: 0, length: 3)
        //rangeOfThreeItems2.firstValue=10//会报错的(因为 rangeOfThreeItems2 被声明成了常量
         //当值类型的实例被声明为常量的时候,它的所有属性也就成了常量。
         //引用类型的类(class)则不一样。把一个引用类型的实例赋给一个常量后,仍然可以修改该实例的变量属 性。
         
        //延迟存储属性
         //延迟存储属性是指当第一次被调用的时候才会计算其初始值的属性。在属性声明前使用 lazy 来标示一个延迟存储 属性。
         //必须将延迟存储属性声明成变量(使用 var 关键字) 因为常量属性在构造过程完成之前必须要有初始值
let manager =  DataManager()
data.append("one")
data.append("two")
       //此时manager实例的 importer 属性还没有被创建
       print(manager.importer.fileName) //data.txt
       //manager实例的 importer 属性现在被创建了
         
//计算属性
        //类、结构体和枚举可以定义计算属性。计算属性不直接存储值,而是提供一个 getter 和一个可选的 setter,来间接获取和设置其他属性或变量的值。
struct
var
var
         }
struct
var
         }
struct
var origin :Point
var size :  Size
var center :  Point{
get
let centerX =  origin.x + (size.width)/2
let centerY =  origin.y + (size.height)/2
return  Point(x: centerX, y: centerY)
                 }
set(newCenter) {
origin.x = newCenter.x - (size.width)/2
origin.y = newCenter.y - (size.height)/2
                 }
             }
         }
var square =  Rect(origin: Point(x: 0.0, y: 0.0), size:Size(width: 10.0, height: 10.0))
let initSquareCenter = square.center
print("\(initSquareCenter.x),\(initSquareCenter.y)")//5.0,5.0
center =  Point(x: 15.0, y: 15.0)
        print("square.origin is now at \(square.origin.x),\(square.origin.y)")//square.origin is now at 10.0,10.0
        //如果计算属性的 setter 没有定义表示新值的参数名,则可以使用默认名称
struct
var origin :Point
var size :  Size
var center :  Point{
get
let centerX =  origin.x + (size.width)/2
let centerY =  origin.y + (size.height)/2
return  Point(x: centerX, y: centerY)
                 }
set
origin.x = newValue.x - (size.width)/2
origin.y = newValue.y - (size.height)/2
                 }
             }
         }
         
         
        //只读计算属性
         //只有 getter 没有 setter 的计算属性就是只读计算属性。只读计算属性总是返回一个值,可以通过点运算符访问,但不能设置新的值
struct
var
var xyz:Double{
return  x*y*z
             }
         }
let mytest =  ttt(x: 10, y: 20, z: 5)
print(mytest.xyz) //1000.0
         
         
//属性观察器
         //属性观察器监控和响应属性值的变化,每次属性被设置值的时候都会调用属性观察器,甚至新的值和现在的值相同的时候也不例外。
        // willSet  在新的值被设置之前调用  ,willSet 观察器会将新的属性值作为常量参数传入  默认名称newValue
         // didSet 在新的值被设置之后立即调用 ,将旧的属性值作为参数传入,可以为该参数命名或者使用默认参数名 oldValue 
let mystepCounter =  stepCounter()
totalSteps
        //willSet stepto  newValue=150
        //DidSet step oldValue= 0
        //前进了150步
totalSteps
        //willSet stepto  newValue=100
        //DidSet step oldValue= 150
        //后腿了50步
         
         
        //全局变量和局部变量
         //计算属性和属性观察器所描述的模式也可以用于全局变量和局部变量。全局变量是在函数、方法、闭包或任何类型之外定义的变量。局部变量是在函数、方法或闭包内部定义的变量。
         
//类型属性
         //实例的属性属于一个特定类型实例, 每次类型实例化后都拥有自己的一套属性值,实例之间的属性相互独立。
         //也可以为类型本身定义属性,不管类型有多少个实例,这些属性都只有唯一一份。这种属性就是类型属性。
         //类型属性是作为类型定义的一部分写在类型最外层的花括号内,因此它的作用范围也就在类型支持的范围内
         //使用关键字static来定义值类型的类型属性,关键字class来为类定义类型属性。
struct
static  var storedTypeProperty = "Some value."
static  var computedTypeProperty: Int {  //只读计算属性
return
         }
enum
static  var storedTypeProperty = "Some value."
static  var computedTypeProperty: Int {  //只读计算属性
return
         }
       
print(SomeStructure.storedTypeProperty)//Some value.
SomeStructure.storedTypeProperty =  "other Value"
print(SomeStructure.storedTypeProperty)//other Value
print(SomeEnumeration.computedTypeProperty)//6
print(SomeClass.computedTypeProperty)//27
   
         
        //声道模型使用 AudioChannel 结构体的实例来表示:
struct
static  let
static  var
var currentLevel :  Int
didSet{
if currentLevel > AudioChannel.thresholdLevel{
currentLevel =  AudioChannel.thresholdLevel
            
             }
if currentLevel > AudioChannel.maxInputLevelForAllChannels{
AudioChannel.maxInputLevelForAllChannels = currentLevel
             
             }
print("thresholdLevel=\(AudioChannel.thresholdLevel)")
             print("currentLevel=\(currentLevel)")
print("maxInputLevelForAllChannels=\(AudioChannel.maxInputLevelForAllChannels)")
             }
             }
         }
var leftChannel =  AudioChannel()
var rightChannel =  AudioChannel()
currentLevel
        //thresholdLevel=10 currentLevel=7 maxInputLevelForAllChannels=7
         
currentLevel=15
        //thresholdLevel=10 currentLevel=10 maxInputLevelForAllChannels=10
         
        
     }
 }
class
static  var storedTypeProperty = "Some value."
static  var computedTypeProperty: Int {  //只读计算属性
return
class  var overrideableComputedTypeProperty: Int { //只读计算属性
return
             } }
class
var totalSteps :  Int
willSet{
            print("willSet stepto  newValue=\(newValue)")
         }
didSet{
             
            print("DidSet step oldValue= \(oldValue)")
if totalSteps
print("前进了\(totalSteps - oldValue)步 ")
else{
print("后腿了\(oldValue - totalSteps)步 ")
             }
 
         }
     }
 }