zoukankan      html  css  js  c++  java
  • Swift—重写-备

    =========================

    重写实例属性

    我们可以在子类中重写从父类继承来的属性,属性有实例属性和静态属性之分,他们在具体实现也是不同的。

    实例属性的重写一方面可以重写getter和setter访问器,另一方面可以重写属性观察者。

    计算静态属性需要使用getter和setter访问器,而存储属性不需要。子类在继承父类后,也可以通过getter和setter访问器重写父类的存储属性和计算属性。

    下面看一个示例:

    1. class Person {  
    2.   
    3.       
    4.   
    5.     var name: String        //存储属性  
    6.   
    7.     var age: Int            //存储属性  
    8.   
    9.       
    10.   
    11.     func description() -> String {  
    12.   
    13.         return "(name) 年龄是: (age)"  
    14.   
    15.     }  
    16.   
    17.       
    18.   
    19.     init (name: String, age: Int) {  
    20.   
    21.         self.name = name  
    22.   
    23.         self.age  = age  
    24.   
    25.     }  
    26.   
    27. }  
    28.   
    29.    
    30.   
    31. class Student: Person {  
    32.   
    33.       
    34.   
    35.     var school: String        
    36.   
    37.       
    38.   
    39.     override var age: Int { //重写属性前面要添加override关键字  
    40.   
    41.         get {  
    42.   
    43.          return super.age      
    44.   
    45.         }  
    46.   
    47.         set {  
    48.   
    49.          super.age = newValue 8 ? 8: newValue    
    50.   
    51.         }  
    52.   
    53.     }                                 
    54.   
    55.          
    56.   
    57.     convenience init() {  
    58.   
    59.         self.init(name: "Tony", age: 18, school: "清华大学")  
    60.   
    61.     }  
    62.   
    63.       
    64.   
    65.     init (name: String, age: Int, school: String) {  
    66.   
    67.         self.school = school  
    68.   
    69.         super.init(name: name, age: age)  
    70.   
    71.     }  
    72.   
    73. }  
    74.   
    75.    
    76.   
    77. let student1 = Student()  
    78.   
    79. print("学生年龄:(student1.age)")  
    80.   
    81. student1.age = 6  
    82.   
    83. print("学生年龄:(student1.age)")  

    从属性重写可见,子类本身并不存储数据,数据是存储在父类的存储属性中的。

    以上示例是重写属性getter和setter访问器,我们还可以重写属性观察者,代码如下:

    1. class Person {  
    2.   
    3.       
    4.   
    5.     var name: String  
    6.   
    7.     var age: Int  
    8.   
    9.       
    10.   
    11.     func description() -> String {  
    12.   
    13.         return "(name) 年龄是: (age)"  
    14.   
    15.     }  
    16.   
    17.       
    18.   
    19.     init (name: String, age: Int) {  
    20.   
    21.         self.name = name  
    22.   
    23.         self.age  = age  
    24.   
    25.     }  
    26.   
    27. }  
    28.   
    29.    
    30.   
    31. class Student: Person {  
    32.   
    33.       
    34.   
    35.     var school: String  
    36.   
    37.       
    38.   
    39.     override var age: Int {  //重写了age属性观察者  
    40.   
    41.      willSet {              //如果只关注修改之前的调用,可以只重写willSet观察者  
    42.   
    43.          print("学生年龄新值:(newValue)")    
    44.   
    45.    
    46.   
    47.      }  
    48.   
    49.      didSet{                //如果只关注修改之后的调用,可以只重写didSet观察者  
    50.   
    51.          print("学生年龄旧值:(oldValue)")   
    52.   
    53.      }  
    54.   
    55.     }                                     
    56.   
    57.       
    58.   
    59.     convenience init() {  
    60.   
    61.         self.init(name: "Tony", age: 18, school: "清华大学")  
    62.   
    63.     }  
    64.   
    65.       
    66.   
    67.     init (name: String, age: Int, school: String) {  
    68.   
    69.         self.school = school  
    70.   
    71.         super.init(name: name, age: age)  
    72.   
    73.     }  
    74.   
    75. }  
    76.   
    77.    
    78.   
    79. let student1 = Student()  
    80.   
    81. print("学生年龄:(student1.age)")  
    82.   
    83. Student1.age = 6                 
    84.   
    85. print("学生年龄:(student1.age)")  

    代码Student1.age = 6修改了age属性,修改前后的输出结果如下:

    学生年龄新值:6

    学生年龄旧值:18

     

    重写静态属性

    在类中静态属性定义使用class或static关键字,但是使用哪一个要看子类中是否重写该属性。class修饰的属性可以被重写,static关键字就不能被重写。

    示例代码如下:

    1. class Account {  
    2.   
    3.       
    4.   
    5.     var amount: Double = 0.0                // 账户金额  
    6.   
    7.     var owner: String = ""                   //账户名  
    8.   
    9.       
    10.   
    11.     var interestRate: Double = 0.0668     //利率  
    12.   
    13.       
    14.   
    15.     //class不能换成static  
    16.   
    17.     class var staticProp: Double {              //静态属性staticProp  
    18.   
    19.         return 0.0668 * 1_000_000  
    20.   
    21.     }  
    22.   
    23.       
    24.   
    25.     var instanceProp: Double {  
    26.   
    27.         return self.interestRate * self.amount  
    28.   
    29.     }  
    30.   
    31. }  
    32.   
    33.    
    34.   
    35. class TermAccount: Account {  
    36.   
    37.       
    38.   
    39.     //class换成static  
    40.   
    41.     override class var staticProp: Double {     //重写静态属性staticProp  
    42.   
    43.         return 0.0700 * 1_000_000  
    44.   
    45.     }  
    46.   
    47. }  
    48.   
    49.    
    50.   
    51. //访问静态属性  
    52.   
    53. print(Account.staticProp)    
    54.   
    55. print(TermAccount.staticProp)   

    由于要被重写所以代码class var staticProp: Double 中的class不能换成static。代码overrideclass var staticProp: Double中的静态属性staticProp可以使用class或static,除非在TermAccount的子类中重写属性staticProp。

    ================================

    重写实例方法

    在子类中重写从父类继承来的实例方法和静态方法。先介绍实例方法的重写。

    下面看一个示例:

     

    1. class Person {   
    2.   
    3.     var name: String  
    4.     var age: Int      
    5.   
    6.     func description() -> String {    //实例方法  
    7.         return "(name) 年龄是: (age)"  
    8.     }      
    9.   
    10.     class func printClass() ->() {    //静态方法  
    11.         print( "Person 打印...")  
    12.     }      
    13.   
    14.     init (name: String, age: Int) {  
    15.         self.name = name  
    16.         self.age  = age  
    17.     }  
    18. }   
    19.   
    20. class Student: Person {      
    21.   
    22.     var school: String      
    23.   
    24.     convenience init() {  
    25.         self.init(name: "Tony", age: 18, school: "清华大学")  
    26.     }      
    27.   
    28.     init (name: String, age: Int, school: String) {  
    29.         self.school = school  
    30.         super.init(name: name, age: age)  
    31.     }      
    32.   
    33.     override func description() -> String {   //重写实例方法description,重写的方法前面要添加关键字override  
    34.       print("父类打印 (super.description())")    
    35.       return "(name) 年龄是: (age), 所在学校: (school)。"  
    36.     }      
    37.   
    38.     override class func printClass() ->() {   //重写静态方法printClass  
    39.         print( "Student 打印...")  
    40.     }  
    41. }   
    42.   
    43. let student1 = student()  
    44. print("学生1:(student1.description())") //调用了description方法   
    45.   
    46. Person.printClass()       
    47. Student.printClass()       

     

    使用super.description()语句调用父类的description方法,其中super指代父类实例。

    重写静态方法printClass,在静态方法中不能访问实例属性。

    调用了description方法。由于在子类中重写了该方法,所以调用的是子类中的description方法。输出结果是:

    父类打印 Tony 年龄是: 18

    学生1:Tony 年龄是: 18, 所在学校: 清华大学。

    为了测试静态方法重写,调用Person.printClass()语言,它是调用父类的printClass静态方法,输出结果是:

    Person 打印...

    调用Student.printClass()语言,它是调用子类的printClass静态方法,输出结果是:

    Student 打印...

     

    重写静态方法

    与类的静态属性定义类似,静态方法使用class或static关键字,但是使用哪一个要看子类中是否重写该方法。class修饰的静态方法可以被重写,static关键字就不能被重写。

    示例代码如下:

     

    1. class Account {      
    2.   
    3.     var owner: String = "Tony"     //账户名      
    4.   
    5.     //不能换成static  
    6.     class func interestBy(amount: Double) -> Double {         //静态方法  
    7.         return 0.08886 * amount  
    8.     }  
    9. }   
    10.   
    11. class TermAccount: Account {//定期账户      
    12.   
    13.     //可以换成static  
    14.     override class func interestBy(amount: Double) -> Double {    //静态方法  
    15.         return 0.09 * amount  
    16.     }  
    17. }   
    18.   
    19. //调用静态方法  
    20. print(Account.interestBy(10_000.00 ))  
    21. print(TermAccount.interestBy(10_000.00 ))  

    由于被重写所以代码class funcinterestBy(amount: Double) -> Double中的class不能换成static。静态方法interestBy可以使用class或static,除非在TermAccount的子类中重写方法interestBy。

    ==============================================

    下标是一种特殊属性。子类属性重写是重写属性的getter和setter访问器,对下标的重写也是重写下标的getter和setter访问器。

    下面看一个示例:

    1. class DoubleDimensionalArray {   
    2.     let rows: Int, columns: Int  
    3.     var grid: [Int]      
    4.     init(rows: Int, columns: Int) {  
    5.         self.rows = rows  
    6.         self.columns = columns  
    7.         grid = Array(count: rows * columns, repeatedValue: 0)  
    8.     }   
    9.     subscript(row: Int, col: Int) -> Int {    //定义下标  
    10.         get {  
    11.             return grid[(row * columns) + col]  
    12.         }         
    13.   
    14.         set {  
    15.             grid[(row * columns) + col] = newValue  
    16.         }  
    17.     }                     //定义下标     
    18.   
    19. }   
    20.   
    21. class SquareMatrix: DoubleDimensionalArray {      
    22.   
    23.     override subscript(row: Int, col: Int) -> Int {   //重写父类下标         
    24.   
    25.         get {           
    26.   
    27.             return super.grid[(row * columns) + col]     
    28.   
    29.         }        
    30.   
    31.         set {               
    32.   
    33.             super.grid[(row * columns) + col] = newValue * newValue   
    34.         }   
    35.   
    36.     }  
    37. }   
    38.   
    39. var ary2 = SquareMatrix(rows: 5, columns: 5)   
    40.   
    41. for var i = 0; i 5; i++ {  
    42.     for var j = 0; j 5; j++ {  
    43.         ary2[i,j] = i + j  
    44.     }  
    45. }  
    46.   
    47. for var i = 0; i 5; i++ {  
    48.     for var j = 0; j 5; j++ {  
    49.         print("  (ary2[i,j])")  
    50.     }  
    51.     print(" ")  
    52. }  

     

    其中super.grid[(row * columns) + col]语句中使用super调用父类的grid属性。

    其中super.grid[(row * columns) + col] = newValue * newValue语句是给父类的grid属性赋值。

  • 相关阅读:
    NLog 在NetCore中实现多实例注入DI, 实现多租户模式
    Linux命令入门篇(二)
    Linux命令入门篇(一)
    uni-app初探之幸运轮盘
    uni-app初探之天气预报小例子
    iOS 底层原理之—dyld 与 objc 的关联
    QT OpenGLWidget高分屏适配时出现的问题
    基于React.js网页版弹窗|react pc端自定义对话框组件RLayer
    面向对象的六大原则
    android混淆日记
  • 原文地址:https://www.cnblogs.com/isItOk/p/5454192.html
Copyright © 2011-2022 走看看