Fortran OOP-03:继承和多态
发布网友
发布时间:2024-09-30 20:44
我来回答
共1个回答
热心网友
时间:2024-10-15 00:58
一个简单的继承示例
Fortran 2003引入了新关键字“extends”,主要为了实现继承功能。
在Fortran中,类的成员函数默认可以被重写(override)。若想禁止重写,则需要使用另一个关键字“non_overridable”。
抽象类
类继承的起点除了通常的类之外,还可以是抽象类。以下是一个示例:
在这个例子中,抽象类没有成员变量,实际上成员变量是允许的。抽象类的成员函数可以是抽象接口(如array_size),也可以是真实的函数(如real64_arr_data_kind)。抽象类也可以继承自另一个抽象类。
定义抽象接口的语法如下:
其中,抽象接口之外的所有类名、函数名、变量等都需要使用import :: 语法引入到抽象接口的定义中。
在抽象类中定义抽象接口使用如下语法:
其中,drferred关键字是必须的,它似乎只在这里使用。
抽象子类不需要实现抽象接口,而一般子类则必须实现抽象接口,否则编译不通过。对于非抽象接口的函数kind,子类可以实现,也可以不实现;若不实现,则采用父类的这个函数。
再次理解class关键字
class关键字如果在传递参数时使用,表示这个参数可以是这个类以及其所有子类。而type参数表示只能是这个类本身。
由于Fortran没有类似final的关键字,所以所有类都存在被继承的可能性。因此,类的成员函数必须使用class参数。
多态指针
class关键字除了在传递参数时使用,还可以用来定义多态指针。以下是一个示例:
可以看到,alice的类型声明为class(People), allocatable,而不是某个type。在后面,它可以申请内存为基类,或者子类,并且表现出对应类型的行为。
Fortran的allocatable本质上是类似指针的,只是它有一些与pointer不同的语法糖。需要申请内存的工作,allocatable通常是心智负担更少的一个选择。
select type语法
实际上,前面的语法已经可以实现大部分的多态功能了。
select type是对Fortran多态功能的进一步拓展。以下是一个示例:
实际上,上述功能完全可以通过重载来实现。不过由于Fortran的重载写起来比较笨重,增加这样一个语法也可以理解。
class(*)语法
class(*)语法是select type语法的进一步增强。以下是一个示例:
我个人是不太喜欢这个语法的,不过不少人拿它当做any类型用。因为class(*)也可以用于变量定义,所以可以由此定义一个无限任意类型的容器,比如:
这个特性也被称为无限多态。
总结
Fortran的继承和多态功能总体上还不错。它没有多继承,不多这种*语法大多数语言也不支持。select type和class(*)有点*,但也是Fortran语法糖不足不得已而为之,建议谨慎使用。