在Fortran

时间:2015-06-08 11:50:11

标签: fortran

我在将参数传递给方法时遇到了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:我已经定义了一个界面,因为它在教程和我经历的文档中都有提及,但我并没有真正理解它。

1 个答案:

答案 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_modcat_mod以获得此可见性?这也不会奏效:speak_cat传递的参数是class(cat)而不是必需的class(animal)。您需要这样做以确保您的class(dog)感到满意。

所以,你的抽象接口块是可行的方法。