我在将参数传递给方法时遇到了fortran问题。
对于上下文,我试图学习如何实现面向对象的编程以维护用Fortran 90编写的程序。
我已经写了一个例子来说明我要做的事情,而且我真的不知道什么是编码它的好方法,以及我在网络上的研究仍然是徒劳的。
module animal_mod
type, abstract :: animal
integer :: age
contains
procedure(speak_interface), deferred :: speak
end type animal
abstract interface
subroutine speak_interface(self)
import :: animal
class(animal), intent(in) :: self
end subroutine
end interface
end module
module cat_mod
use animal_mod
type, extends (animal) :: cat
character (len=8) :: fur
contains
procedure :: speak => speak_cat
end type cat
contains
subroutine speak_cat(self)
class(cat), intent(in) :: self
print *, "Meow"
end subroutine
end module
program animals
use cat_mod
implicit none
type(cat) :: my_cat
my_cat%fur="Shiny"
my_cat%age=3
call make_it_speak(my_cat)
end program animals
subroutine make_it_speak(my_animal)
use animal_mod
class(animal), intent(in) :: my_animal
call my_animal%speak()
end subroutine
问题在于我将变量声明为类型(cat),而我的子例程将类(动物)作为参数。但是,由于抽象,我不能声明一个类型(动物)。
你能帮帮我这个话题吗?
PS:我已经定义了一个界面,因为它在教程和我经历的文档中都有提及,但我并没有真正理解它。
答案 0 :(得分:1)
您有两个问题:关于分段错误和界面。
要回答有关分段错误的问题,子例程make_it_speak
具有多态参数my_animal
。它是多态的,因为它被声明为class(animal)
。这要求主程序(调用此子程序)必须具有可用的显式接口。将子例程放入animal_mod
通过使用关联来实现。你可以在其他问题和答案中找到很多讨论。
来到animal_mod
中的抽象界面,让我们孤立地看一下该模块。
当声明抽象类型speak
的延迟类型绑定过程animal
时,必须指定其接口。同样,此接口必须是该类型的显式接口。接口块是提供此显式接口的一种方法。另一种方法是拥有一个程序,可能称为speak_animal
。但是,对于后者,你不再真正推迟。
为什么不能使用speak_cat
作为一个合适的实现,作为界面而不是重复speak_interface
?一个主要原因是模块animal_mod
speak_cat
内部不可见。通过使用关联使其可用是不可能的,因为那时会存在循环依赖。
如何合并animal_mod
和cat_mod
以获得此可见性?这也不会奏效:speak_cat
传递的参数是class(cat)
而不是必需的class(animal)
。您需要这样做以确保您的class(dog)
感到满意。
所以,你的抽象接口块是可行的方法。