在 Fortran 2003 中,如果一个变量在超类中声明为 PRIVATE,则子类将无法访问它。但是如果所有变量都声明为PUBLIC,程序就会失去“信息隐藏”的属性。
有没有办法在 Fortran 面向对象编程中同时采用“数据继承”和“信息隐藏”?如果不是在 2003 年,那么 Fortran 2008 有什么改进吗?
在 Fortran 2003 中,如果一个变量在超类中声明为 PRIVATE,则子类将无法访问它。但是如果所有变量都声明为PUBLIC,程序就会失去“信息隐藏”的属性。
有没有办法在 Fortran 面向对象编程中同时采用“数据继承”和“信息隐藏”?如果不是在 2003 年,那么 Fortran 2008 有什么改进吗?
我的理解是,在 Fortran 2003 中,模块中定义的派生类型的任何私有组件都可以在该模块中直接访问。一个暗示(我没有测试过)是这些私有组件可以从同一个模块中定义的子类型直接访问,但不能从另一个模块中声明的子类型访问。正如我所说,我没有对此进行测试,并且有待纠正。
如果您有一个实现子模块的编译器,那么私有组件也可以在后代子模块中直接访问。我认为子模块是在 2003 年标准发布后在技术报告中引入的,现在已包含在 2008 年标准中,但没有多少广泛使用的编译器实现该功能。
尽管有这些标准,但我不清楚由于无法直接访问超类型的私有组件而损失了多少。在面向对象的世界中,将所有组件设为私有(尽管其他语言使用其他词来表达这个想法)并仅通过访问器方法提供访问似乎很常见——在 Fortran 术语中,它们将是分配给或用于返回私有组件的值。这种内部数据表示与外部访问的严格分离允许在不改变其他过程访问数据的方式的情况下更改内部表示,并且这种分离通常被认为是一个好主意。
访问器过程的使用还允许访问控制的更细粒度和微妙的应用,例如,通过提供一个过程,该过程在构造派生类型的实例时设置组件的值,但没有过程来修改之后的组件。
在我看来,具有公共访问器过程的私有组件提供了大部分数据继承和信息隐藏,但我有兴趣阅读该问题的其他答案。
不幸的是,在 Fortran 中没有直接的方法来定义派生类型的组件,这些组件可以从扩展派生类型的类型绑定过程中访问,但在其他情况下是隐藏的。正如高性能标记所指出的,派生类型组件的访问是基于模块的:派生类型的私有组件只能从该模块内访问。
实用的解决方案是定义所有应该可以从外部访问的公共内容,无论您是想仅在扩展派生类型还是在其他地方使用这些组件。在这个概念中,私有和公共仅决定您是否可以更改内部细节(私有)或不更改(公共),而不必担心对您或其他人代码的其他部分的后果。
另外,请注意,即使拥有像 C++ 中的受保护成员这样的语言特性,也不能解决基本问题:一旦您声明某些东西不是私有的,更改其行为将在其他代码中引起副作用,最终您甚至不会意识到(例如,某人扩展了您的派生类型并依赖于可以从扩展类型访问的某些成员的行为。)