Swift12-继承

定义一个基类、子类生成、重写、防止重写。

 

一个类可以继承另一个类的方法、属性和其他特征。

被继承的类叫超类(可以是一个父类或多个父类)。

Swift中,类可以调用和访问超类的方法、属性和下标。并且可以重写这些方法、属性和下标来优化或修改它们的行为。Swift会检查你的重写定义在超类中是否有匹配的定义,以此确保你的重写行为正确。

 

定义一个基类:

不继承其它类的类称为基类。

Swift中没有一个通用的基类用于继承,只要一个类没有继承其它类它就是基类。

class Vehicle{

  var currentSpeed=0.0

  var description:String{

    return "speed is \(currentSpeed)"

  }

  func makeNoise(){

    //

  }

}

 

子类生成:

子类生成指的是在一个已有类的基础上创建一个新的类。子类继承超类的特性,并且可以进一步完善,还可以添加新的特性。

为了指明某个类的超类,将超类名写在子类名的后面,用冒号分隔:

class Bicycle:Vehicle{

  var hasBasket=false

}

新的Bicycle类自动获得Vehicle类的所有特性。除了继承自超类的特性,Bicycle类还定义了自己的hasBasket存储属性。

子类还可以被其它类继承。

 

重写:

子类可以为继承来的实例方法、类方法、实例属性、或下标提供自己定制的实现。将其称为重写。

如果要重写某个特性,需要在重写定义的前面加上override关键字。这表明了提供一个重写版本,而非错误地提供了一个相同的定义(即没有重写override关键字时,相同名称导致歧义错误)。意外的重写行为可能会导致不可预知的错误,任何缺少override关键字的重写都会在编译时被诊断为错误。

override关键字会提醒Swift编译器去检查该类的超类(或其中一个父类)是否有匹配重写版本的声明。

 

访问超类的方法,属性及下标:

当你在子类中重写超类的方法、属性或下标时,有时在你的重写版本中使用已经存在的超类实现会很有益。

在合适的地方,可以通过使用super前缀来访问超类版本的方法、属性或下标:

1)在方法someMethod()的重写实现中,可以通过super.someMethod()来调用超类版本的someMethod()方法。

2)在属性someProperty的getter或setter的重写实现中,可以通过super.SomeProperty来访问超类版本的someProperty属性。

3)在下标的重写实现中,可以通过super[someIndex]来访问超类版本中的相同下标。

 

重写方法:

在子类中,可以重写继承来的实例方法或类方法,提供一个定制或替代的方法实现。

class Train:Vehile{

  override func makeNoise(){

    print("Choo Choo")

  }

}

 

重写属性:(可以重写超类的存储/计算型属性成子类的计算型属性,或重写带有观察器的属性)

可以重写继承来的实例属性或类型属性,提供自己定制的getter和setter,或添加属性观察器使重写的属性可以观察属性值什么时候发生改变。

重写属性的getter和setter:

可以提供定制的getter(或setter)来重写任意继承来的属性,无论继承来的属性是存储型的还是计算型的属性。

子类并不知道继承来的属性是存储型还是计算型,它只知道继承来的属性会有一个名字和类型。在重写一个属性时,必须将它的名字和类型都写出来。这样才能使编译器去检查你重写的属性是与超类中同名同类型的属性相匹配。

可以将一个继承来的只读属性重写成一个读写属性。但不能将一个继承来的读写属性重写为一个只读属性。

 

(单一继承的子类是父类的超集,父类类型的变量引用子类实例可以达到多态,子类类型的变量则不可引用父类。所以子类重写父类的可读可写属性时,不能重写成只读属性)

如果不想在重写版本中的getter里修改继承来的属性值,可以直接通过super.someProperty来返回继承来的值。

 

重写属性观察器:

可以通过重写属性为一个继承来的属性添加属性观察器。这样一来,当继承来的属性值发生改变时,就会被通知,无论原来那个属性原本是如何实现的。

 

防止重写:

通过把方法、属性或下标标记为final来防止它们被重写,只需要在声明关键字前加上final修饰符即可。

重写带有final标记的方法、属性或下标时,会编译出错。在类扩展中的方法、属性或下标也可以在扩展的定义里标记为final的。

可以通过在关键字class前添加final修饰符(final class)来将整个类标记为final的。这样的类是不可被继承的,试图继承这样的类会编译出错。

class Base{

  final var a:Int=0

}

//a不可被重写

 

posted @ 2020-05-08 11:19  吉吉boy  阅读(119)  评论(0编辑  收藏  举报