import UIKit
class Vehicle {
var currentSpeed = 0.0
var description: String {
return "traveling at \(currentSpeed) miles per hour"
}
func makeNoise() {
// 什么也不做-因为车辆不一定会有噪音
}
}
class Car:Vehicle {
override init(){
super.init()
}
var gear = 1;
override var description:String{
return super.description + "in gear \(gear)"
}
}
class AutomaticCar :Car {
override var currentSpeed:Double{
didSet{
gear = Int(currentSpeed/10.0)+1
}
}
}
struct myStruct {
var one:Double
init(){
one = 32.0
}
}
struct Celsius {
var temperatureInCelsius: Double
init(fromFahrenheit fahrenheit: Double) {
temperatureInCelsius = (fahrenheit - 32.0) / 1.8
}//该构造器拥有一个构造参数,其外部名字为fromFahrenheit,内部名字为fahrenheit
init(fromKelvin kelvin: Double) {
temperatureInCelsius = kelvin - 273.15
}
}
struct Color {
let red,green,blue:Double
init(red:Double,green:Double,blue:Double){
self.red=red;
self.green=green;
self.blue=blue;
}
init(MyWhite white:Double){
red=white
green=white
blue=white
}
init(_ white:Double){
red=white
green=white
blue=white
}
}
class myQuestion {
let text:String
var response:String?
init(text:String){
self.text=text;
}
func ask(){
print(text)
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//重写(Overriding)
//子类可以为继承来的实例方法,类方法,实例属性。或下标脚本提供自己定制的实现我们把这种行为叫重写
//如果要重写某个特性,需要在重写定义的前面加上override关键字。表明你是想提供一个重写版本,而非错误的提供一个相同的定义。
//在方法someMethod的重写实现中通过super.someMethod()来调用超类的someMethod方法通过super.someProperty来访问超类的someProperty属性,通过super[someIndex]来访问超类版本中的下标脚本
let car=Car()
car.currentSpeed=12
car.gear=3
print("Car:\(car.description)")//Car:traveling at 12.0 miles per hourin gear 3
let auto = AutomaticCar();
auto.currentSpeed = 45;
print("AutomaticCar:\(auto.description)")//AutomaticCar:traveling at 45.0 miles per hourin gear 5
//防止重写
//通过把方法,属性,下标脚本标记为final来防止它们被重写(final var,final func ,final class ,final subscript)
//在关键字class前添加final特性来将整个类标记为final的,这样的类是不可被继承的。
//构造过程(Initialization)
//构造过程是使用类、结构体或枚举类型的一个实例准备过程。在新实例可用之前必须执行这个过程,具体操作包括设置实例中每个存储型属性的初始值和执行其他必须的设置或初始化工作。
//类和结构体在创建实例时,必须为所有存储属性设置合适的初始值。存储型属性的值不能处于一个未知的状态
let f = myStruct()
print("The default one is\(f.one)")//The default one is32.0
let boilingPointOfWater = Celsius(fromFahrenheit: 212.0)
print(boilingPointOfWater.temperatureInCelsius)//100.0
let freezingPointOfWater = Celsius(fromKelvin: 273.15)
print(freezingPointOfWater.temperatureInCelsius)//0.0
//参数的内部名称和外部名称
//跟函数和方法参数相同,构造参数也存在一个在构造器内部使用的参数名字和一个在调用构造器时使用的外部参数名字。然而,构造器并不像函数和方法那样在括号前有一个可辨别的名字。所以在调用构造器时,主要通过构造器中的参数名和类型来确定需要调用的构造器。
//如果在定义构造器时没有提供参数的外部名字,swift会为每个构造器的参数自动生成一个跟内部名字相同的外部名。
let color = Color(red: 1.0, green: 0, blue: 1.0)
let color22 = Color(MyWhite: 0.5)
//如果你不希望为构造器的某个参数提供外部名字,你可以使用下划线(_)来显示描述它的外部名
let color33 = Color(0.5)
let cheeseQuestion = myQuestion(text: "Do you like cheese?")
cheeseQuestion.response = "Yes, I do like cheese."
//构造过程中常量属性的修改
//可以在构造过程中的任意时间点修改常量的值,一旦常量属性被赋值,它将永远不可更改
//结构体的逐一成员构造器
//结构体的逐一成员构造器
//如果结构体对所有存储型属性提供了默认值且自身没有提供定制的构造器,它们能自动获得一个逐一成员构造器
struct Size{
var width = 0.0,height = 0.0
}
let mySize = Size(width: 2.0, height: 2.0)
//值类型的构造器代理
//构造器可以通过调用其它构造器来完成实例的部分构造过程。这一过程称为构造器代理。它能减少多个构造器间的代码重复
//构造器代理的实现规则和形式在值类型和类类型中有所不同。值类型不支持继承,所以构造器代理的过程相对简单,因为它们只能代理給本身提供的其它构造器。类则不同,它可以继承自其它类。
struct Point{
var x = 0.0 ,y = 0.0
}
struct Rect{
var origin = Point()
var size = Size()
init(){}
init(origin: Point,size :Size){
self.origin = origin;
self.size = size;
}
init(center:Point,size:Size){
let originX = center.x - (size.width/2)
let originY = center.y - (size.height/2)
self.init(origin:Point(x: originX, y: originY),size:size)
}
}
//类的继承和构造过程
//类里面的所有存储型属性,包括所有继承自父类的属性都必须在构造过程中设置初始值
//swift提供了两种类型的类构造器来确保所有类实例中存储属性都能获得初始值,它们分别是指定构造器和便利构造器
//指定构造器是类中最主要的构造器。一个指定构造器将初始化类中提供的所有属性,根据父类链往上调用父类的构造器来实现父类的初始化。每个类都必须拥有至少一个指定构造器。
//便利构造器是类中比较次要的、辅助型的构造器。可以定义饿便利构造器来调用同一个类中的指定构造器。
//1.指定构造器必须调用其直接父类的指定构造器
//2.便利构造器必须调用同一类中定义的其它构造器
//3.便利构造器必须最终以调用一个指定构造器结束
let myttt = twoTest()
print("\(myttt.description)")//5...
//子类定义了一个自定义的指定构造器init() 这个指定构造器和父类的指定构造器相匹配,所以子类的指定构造器需要带上override修饰符
/**
//自动构造器的继承
//1.子类不会默认继承父类的构造器。但是如果特定条件可以满足,父类构造器时可以被自动继承的。
//2.如果子类没有定义任何指定构造器,它将自动继承所有父类的指定构造器
//3.如果子类提供了所有父类指定构造器的实现它将自动继承所有父类的便利构造器
let Foodname = Food(name: "orange")
print(Foodname.name)//orange
let Foodname2 = Food()
print(Foodname2.name)//apple
//Food类中的构造器init(name: String)被定义为一个指定构造器,Food类没有父类,所以init(name: String)构造器不需要调用super.init()来完成构造
*/
let onefood = RecipeIngredient()
print("\(onefood.name) === \(onefood.quantity)")//apple === 1
//注意:RecipeIngredient的父类Food有一个便利构造器init().这个构造器因此也被RecipeIngredient继承。这个继承的init()和Food提供的版本是一样的,除了它是将任务代理给RecipeIngredient版本的init(name:String)而不是Food提供的版本
//所以调用顺序为"1111111111"--》"333333333333"--》"44444444444444"--》"2222222222"
let twofood = RecipeIngredient(name: "DLG")
print("\(twofood.name) === \(twofood.quantity)")//DLG === 1
let threefood = RecipeIngredient(name: "HHH", quantity: 6)
print(threefood.name)
var breakfastList=[ShoppingListItem(),
ShoppingListItem(name: "Milk"),
ShoppingListItem(name: "Eggs", quantity: 6),
]
breakfastList[0].name="Orange juice"
breakfastList[0].purchased=true
for item in breakfastList{
print(item.description)
}
// 1 x Orange juicetrue
// 1 x Milkfalse
// 6 x Eggsfalse
let someCreature = Animal(sep: "Griaffe")//someCreature的类型是Animal?而不是Animal
if let giraffe = someCreature{
print("\(giraffe.species)")//Griaffe
}
let someCreature2 = Animal(sep: "")
if someCreature2 == nil{
print("animal 初始化失败!")//animal 初始化失败!
}
//枚举类型的可失败构造器
//可以通过构造一个带一个或多个参数的可失败构造器来获取枚举类型中特定的枚举成员。还能在参数不满足枚举成员期望的条件时,构造失败
enum TemperatureUnit{
case kel, Cel, Fah
init?(symbol:Character){
switch symbol{
case "K":
self = .kel
case "C":
self = .Cel
case "F":
self = .Fah
default:
return nil
}
}
}
let fff = TemperatureUnit(symbol: "F")
if fff != nil{
print("succeed")//succeed
}
let nnn = TemperatureUnit(symbol: "N")
if nnn == nil{
print("failed")//failed
}
//带原始值的枚举类型的可失败构造器
//带原始值的枚举类型会自带一个可失败构造器init?(rawValue:),该可失败构造器有一个名为rawValue的默认参数,其类型和枚举类型的原始值类型一致,如果该参数的值能和枚举类型成员所带的原始值匹配,则该构造器构造一个带此原始值的枚举成员,否则构造失败。
enum Tempera:Character{
case Kel="K",Cel="C", Fah="F"
}
let fahre=Tempera(rawValue: "F")
if fahre != nil{
print("succeed")//succeed
}
let unknow = Tempera(rawValue: "X")
if unknow == nil{
print("failed")//failed
}
}
}
//可失败构造器
//如果一个类、结构体或枚举类型的对象,在构造器自身的过程中有可能失败,则为其定义一个可失败构造器,是非常有用的。所谓的失败是指给构造器传入无效的参数值,或缺少某种所需的外部资源等。
struct Animal {
let species : String
init?(sep:String){
if sep.isEmpty{return nil}
self.species = sep
}
}//严格来说构造器是不支持返回值的,所以即使在失败的情况下用到了return,也不要在成功的情况下用到return
//由于ShoppingListItem为自己引入的所有属性都提供了默认值,并且自己没有定义任何构造器,ShoppingListItem将自动继承所有父类中的指定构造器和便利构造器
class ShoppingListItem:RecipeIngredient {
var purchased = false
var description : String{
var output = "\(quantity) x \(name)"
output += purchased ? "true": "false"
return output
}
}
class RecipeIngredient: Food {
var quantity : Int
var age :Int?
init(name:String,quantity:Int){
self.quantity=quantity
print("44444444444444")
super.init(name:name)
}
override convenience init(name: String) {
print("333333333333")
self.init(name:name,quantity:1)
}
}
class Food {
var name : String
init(name:String){
print("2222222222")
self.name=name
}
convenience init(){
print("1111111111")
self.init(name:"apple")
}
}
class mytest {
var one = 0
var description : String{
return "\(one)..."
}
}
class twoTest: mytest {
override init() {
super.init()
one = 5
}
}