继承

作者: 奔跑的_猿 | 来源:发表于2017-03-09 10:52 被阅读0次

继承我们可以理解为一个类获取了另外一个类的方法和属性。
当一个类继承其它类时,继承类叫子类,被继承类叫超类(或父类)
在 Swift 中,类可以调用和访问超类的方法,属性和下标脚本,并且可以重写它们。
我们也可以为类中继承来的属性添加属性观察器。

  • 基类
    没有继承其它类的类,称之为基类(Base Class)。
    以下实例中我们定义了基类 StudDetails ,描述了学生(stname)及其各科成绩的分数(mark1、mark2、mark3):
class StudDetails {
    var stname: String!
    var mark1: Int!
    var mark2: Int!
    var mark3: Int!
    init(stname: String, mark1: Int, mark2: Int, mark3: Int) {
        self.stname = stname
        self.mark1 = mark1
        self.mark2 = mark2
        self.mark3 = mark3
    }
}
let stname = "swift"
let mark1 = 98
let mark2 = 89
let mark3 = 76

let sds = StudDetails(stname:stname, mark1:mark1, mark2:mark2, mark3:mark3);

print(sds.stname)
print(sds.mark1)
print(sds.mark2)
print(sds.mark3)

以上程序执行输出结果为:
swift
98
89
76

  • 子类
    子类指的是在一个已有类的基础上创建一个新的类。
    为了指明某个类的超类,将超类名写在子类名的后面,用冒号(:)分隔,语法格式如下
class SomeClass: SomeSuperclass {
    // 类的定义
}

实例
以下实例中我们定义了超类 StudDetails,然后使用子类 Tom 继承它:

class StudDetails
{
    var mark1: Int;
    var mark2: Int;
    
    init(stm1:Int, results stm2:Int)
    {
        mark1 = stm1;
        mark2 = stm2;
    }
    
    func show()
    {
        print("Mark1:\(self.mark1), Mark2:\(self.mark2)")
    }
}

class Tom : StudDetails
{
    init()
    {
        super.init(stm1: 93, results: 89)
    }
}

let tom = Tom()
tom.show()

以上程序执行输出结果为:
Mark1:93, Mark2:89

  • 重写(Overriding)
    子类可以通过继承来的实例方法,类方法,实例属性,或下标脚本来实现自己的定制功能,我们把这种行为叫重写(overriding)。
    我们可以使用 override 关键字来实现重写。
    访问超类的方法、属性及下标脚本
    你可以通过使用super前缀来访问超类的方法,属性或下标脚本。
    重写 访问方法,属性,下标脚本
    方法 super.somemethod()
    属性 super.someProperty()
    下标脚本 super[someIndex]
    重写方法和属性

重写方法
在我们的子类中我们可以使用 override 关键字来重写超类的方法。

以下实例中我们重写了 show() 方法:

class SuperClass {
    func show() {
        print("这是超类 SuperClass")
    }
}

class SubClass: SuperClass  {
    override func show() {
        print("这是子类 SubClass")
    }
}

let superClass = SuperClass()
superClass.show()

let subClass = SubClass()
subClass.show()

以上程序执行输出结果为:
这是超类 SuperClass
这是子类 SubClass

  • 重写属性
    你可以提供定制的 getter(或 setter)来重写任意继承来的属性,无论继承来的属性是存储型的还是计算型的属性。
    子类并不知道继承来的属性是存储型的还是计算型的,它只知道继承来的属性会有一个名字和类型。所以你在重写一个属性时,必需将它的名字和类型都写出来。
  • 注意点:
    如果你在重写属性中提供了 setter,那么你也一定要提供 getter。
    如果你不想在重写版本中的 getter 里修改继承来的属性值,你可以直接通过super.someProperty来返回继承来的值,其中someProperty是你要重写的属性的名字。
    以下实例我们定义了超类 Circle 及子类 Rectangle, 在 Rectangle 类中我们重写属性 area:
class Circle {
    var radius = 12.5
    var area: String {
        return "矩形半径 \(radius) "
    }
}

// 继承超类 Circle
class Rectangle: Circle {
    var print = 7
    override var area: String {
        return super.area + " ,但现在被重写为 \(print)"
    }
}

let rect = Rectangle()
rect.radius = 25.0
rect.print = 3
print("Radius \(rect.area)")

以上程序执行输出结果为:
Radius 矩形半径 25.0 ,但现在被重写为 3

  • 重写属性观察器
    你可以在属性重写中为一个继承来的属性添加属性观察器。这样一来,当继承来的属性值发生改变时,你就会监测到。
    注意:你不可以为继承来的常量存储型属性或继承来的只读计算型属性添加属性观察器。
class Circle {
    var radius = 12.5
    var area: String {
        return "矩形半径为 \(radius) "
    }
}

class Rectangle: Circle {
    var print = 7
    override var area: String {
        return super.area + " ,但现在被重写为 \(print)"
    }
}


let rect = Rectangle()
rect.radius = 25.0
rect.print = 3
print("半径: \(rect.area)")

class Square: Rectangle {
    override var radius: Double {
        didSet {
            print = Int(radius/5.0)+1
        }
    }
}


let sq = Square()
sq.radius = 100.0
print("半径: \(sq.area)")

半径: 矩形半径为 25.0 ,但现在被重写为 3
半径: 矩形半径为 100.0 ,但现在被重写为 21

  • 防止重写
    我们可以使用 final 关键字防止它们被重写。
    如果你重写了final方法,属性或下标脚本,在编译时会报错。
    你可以通过在关键字class前添加final特性(final class)来将整个类标记为 final 的,这样的类是不可被继承的,否则会报编译错误。
final class Circle {
    final var radius = 12.5
    var area: String {
        return "矩形半径为 \(radius) "
    }
}
class Rectangle: Circle {
    var print = 7
    override var area: String {
        return super.area + " ,但现在被重写为 \(print)"
    }
}

let rect = Rectangle()
rect.radius = 25.0
rect.print = 3
print("半径: \(rect.area)")

class Square: Rectangle {
    override var radius: Double {
        didSet {
            print = Int(radius/5.0)+1
        }
    }
}

let sq = Square()
sq.radius = 100.0
print("半径: \(sq.area)")

由于以上实例使用了 final 关键字不允许重写,所以执行会报错:
error: var overrides a 'final' var
override var area: String {
^
note: overridden declaration is here
var area: String {
^
error: var overrides a 'final' var
override var radius: Double {
^
note: overridden declaration is here
final var radius = 12.5
^
error: inheritance from a final class 'Circle'
class Rectangle: Circle {
^
文章转载自:http://www.runoob.com/swift/swift-inheritance.html

相关文章

  • 继承 继承

    属性拷贝 继承不单单能通过原型链实现,也能通过其他方式实现,属性拷贝就是其中一种方法。 通过属性拷贝也能实现继承子...

  • 继承(单继承,多继承)

    将共性的内容放在父类中,子类只需要关注自己特有的内容 python中所有的内容都是对象,所有的对象都直接或间接继承...

  • js继承方式

    类式继承 构造函数继承 组合继承 类式继承 + 构造函数继承 原型式继承 寄生式继承 寄生组合式继承 寄生式继承 ...

  • Python-学习之路-08 OOP -02

    单继承和多继承 单继承:每个类只能继承一个类 多继承:每个类可以继承多个类 单继承的多继承的优缺点 菱形继承/钻石...

  • 原型相关(二)

    1.继承 继承方式:接口继承(只继承方法签名)实现继承(继承实际的方法)ECMAScript只支持实现继承,并且主...

  • 继承

    继承的引入和概述 继承案例和继承的好处 继承的弊端 Java中继承的特点 继承的注意实现和什么时候使用继承 继承中...

  • Java面向对象三大特性之继承

    继承 一、继承的特点 Java只支持单继承单继承 多继承 单继承、多继承优缺点①单继承优点:提高了代码的复用性,让...

  • 7、面向对象的程序设计3(《JS高级》笔记)

    三、继承 许多OO语言都支持两种继承方式:接口继承和实现继承。接口继承只继承方法签名,而实现继承则继承实际方法。由...

  • 【重学前端】JavaScript中的继承

    JavaScript中继承主要分为六种:类式继承(原型链继承)、构造函数继承、组合继承、原型式继承、寄生式继承、寄...

  • js之继承

    文章主讲 JS 继承,包括原型链继承、构造函数继承、组合继承、寄生组合继承、原型式继承、 ES6 继承,以及 多继...

网友评论

      本文标题:继承

      本文链接:https://www.haomeiwen.com/subject/thrwgttx.html