第 44 讲:结构(三):结构和继承机制
在 C# 里,官方团队为了灵活使用这个编程语言,就把 C# 设计得非常灵活。C# 里的结构虽然不能自定义继承关系,但可以自定义实现接口。而因为结构是自动从 ValueType
这个类派生起来的,因此今天我们会把结构的继承机制和实现接口的机制都给大家介绍一下。
Part 1 结构实现接口的语法
和类的接口实现完全一样,结构的接口实现,写法完全没有区别。只是因为结构不能自定义继承关系,因此我们没有类的继承机制了,只剩下接口的实现列表。
举个例子。假设我们有一个自定义的整数类型 Integer
,那么它显然可以实现比如下面这样的一些接口。
对吧,比如说这里的 ICalculatable
对应了加减乘除模五大基本算术运算,IFormattable
对应了输出一个整数数据的字符串的时候,的排版格式(比如要不要添加开头的正负号啊,要不要三位一分节之类的),IConvertible
定义了这个类型和其他基本数据类型的转换方法。
只需要挨个实现接口里的成员,就 OK 了。用法和类的接口实现是没有区别的,而且也分显式接口实现和隐式接口实现两种,写法都和之前讲过的那样,没有区别。
Part 2 ValueType
是个什么幺蛾子
之前我们就简单说过了,ValueType
是一个引用类型(用类表达出来的,而不是接口)。而这个 ValueType
是没有基类型继承的自定义关系的,默认是从 object
派生。那么 ValueType
里到底有一些什么成员呢?
呃,其实不必多说。你照着 object
来看就可以了。因为是完全一样的。之前说过,object
有这些成员:
无参构造器;
Equals
方法(virtual
修饰,可重写);ReferenceEquals
方法(static
修饰,不可重写);ToString
方法(virtual
修饰,可重写);GetHashCode
方法(virtual
修饰,可重写);operator ==
等号运算符(可重载);operator !=
不等号运算符(可重载)。
而 ValueType
也是这些成员。不过因为 ValueType
是 object
的一个子类型,所以标记的不是 virtual
,而是 override
。不过,因为 ValueType
还提供给别的结构继承,因此本身是没有标记 sealed
关键字的,因此这些原本标记 virtual
关键字的方法都可以重写。
至于运算符,本身就不可能防止重载,它的继承和重载机制和重写不同,所以运算符重载是无法通过继承来防止的。换句话说,运算符定不定义,全看你自己的心情;心情好,你自己定义,编译器也不会管你;心情不好,也可以不管。
不过请记住一点。object
可以实例化,但 ValueType
是抽象类型,不可实例化。
Part 3 总结
是的,本文就这一点点内容。是不是觉得文章的内容分布有点不均匀?觉得有些文章内容多,有些文章内容少?
因为确实,这个部分的内容就这一点;但是不分出来单独讲解的话,又没有那么正式,毕竟它还是算一个很重要的知识点。