子类模块为何不能重用父类模块的抽象接口?
以下代码可以正常编译运行module super_class !父类
implicit none
private
type,public::point
real::x=0.0
real::y=0.0
procedure(sub),pointer::p=>null() !过程指针作为成员变量
contains
procedure,pass::point_new !父类构造函数
procedure,pass::printSum!打印成员变量之和
end type point
abstract interface !抽象接口
subroutine sub(me,x,f)
import::point !导入宿主定义
class(point),intent(inout)::me
real,dimension(:), intent(in)::x
real,intent(out) ::f
end subroutine sub
end interface
contains
subroutine point_new(me,x,y) !父类构造函数
class(point),intent(inout)::me
real,intent(in)::x
real,intent(in)::y
me%x=x
me%y=y
end subroutine point_new
subroutine printSum(me,pp)
class(point),intent(inout)::me
procedure(sub)::pp !任何与子例程sub形参列表相同的子例程都能传入
real::f
me%p=>pp !过程指针确定指向
call me%p(,f) !相当于call me%pp()
write(*,*)'父类sum=',f
end subroutine printSum
end module super_class
module sub_class !子类
use super_class
implicit none
private
type,public,extends(point)::point3d
real::z=0.0
contains
procedure,pass::point3d_new !子类构造函数
procedure,pass::printSum !打印成员变量之和 子类重写覆盖
end type point3d
abstract interface !抽象接口
subroutine sub(me,x,f)
import::point !导入宿主定义
class(point),intent(inout)::me
real,dimension(:), intent(in)::x
real,intent(out) ::f
end subroutine sub
end interface
contains
subroutine point3d_new(me,x,y,z) !子类构造函数
class(point3d),intent(inout)::me
real,intent(in)::x
real,intent(in)::y
real,intent(in)::z
call me%point%point_new(x,y) !调用父类的构造函数
me%z=z
end subroutine point3d_new
subroutine printSum(me,pp) !子类重写覆盖
class(point3d),intent(inout)::me
procedure(sub)::pp !任何与子例程sub形参列表相同的子例程都能传入
real::f
me%p=>pp !过程指针确定指向
call me%p(,f) !相当于call me%pp()
write(*,*)'子类sum=',f
end subroutine printSum
end module sub_class
program main !主程序
use super_class
use sub_class
implicit none
type(point)::a
type(point3d)::b
call a%point_new(1.0,1.0)
call a%printSum(sss)
call b%point3d_new(2.0,2.0,2.0)
call b%printSum(sss)
contains
subroutine sss(me,x,f) !抽象接口具体实现
class(point),intent(inout)::me
real,dimension(:), intent(in)::x
real,intent(out) ::f
f=sum(x)
end subroutine sss
end program main
但是将子类模块中的抽象接口相关语句注释后
编译将报错
按理说通过use语句
子类模块可以导入父类模块相关内容从而减少代码量
为何子类模块必须要把父类模块的抽象接口代码重写一遍呢?
module super_class
中添加
public :: sub vvt 发表于 2019-7-18 22:03
module super_class
中添加
public :: sub
原来是这样
一直纳闷抽象接口怎么没有接口名 赞,mark 码一下 我重现了一下,其实代码上的问题,个人感觉不在类的继承上。而在于printSum上。
module m_father
implicit none
private
type,public :: t_father
procedure(temp),nopass,pointer :: p
end type t_father
abstract interface
function temp(a) result(out)
implicit none
integer,intent(in) :: a
integer :: out
end function temp
end interface
end module m_father
module m_son
use m_father
implicit none
private
type,extends(t_father),public :: t_son
integer :: a
end type t_son
end module m_son
program main
use m_son
implicit none
type(t_son) :: one
one%p=>jiecheng
print*,one%p(5)
contains
function jiecheng(a) result(out)
implicit none
integer,intent(in) :: a
integer :: out
integer :: i
out=1
do i=2,a
out=out*a
end do
end function jiecheng
end program main
我测试了,这样是没有问题的 本帖最后由 weixing1531 于 2019-8-2 22:17 编辑
lookbook 发表于 2019-8-2 15:42
我重现了一下,其实代码上的问题,个人感觉不在类的继承上。而在于printSum上。
module m_father
你的接口是静态方法,子类没有重写父类方法
我的接口是实例方法,子类重写了父类方法,抽象接口作为实例方法形参
可能区别就在这
我的代码假如不重写父类方法也可以不用公开抽象接口
module super_class !父类
implicit none
private
type,public::point
real::x=0.0
real::y=0.0
procedure(sub),pointer::p=>null() !过程指针作为成员变量
contains
procedure,pass::point_new !父类构造函数
procedure,pass::printSum!打印成员变量之和
end type point
abstract interface !抽象接口
subroutine sub(me,x,f)
import::point !导入宿主定义
class(point),intent(inout)::me
real,dimension(:), intent(in)::x
real,intent(out) ::f
end subroutine sub
end interface
contains
subroutine point_new(me,x,y) !父类构造函数
class(point),intent(inout)::me
real,intent(in)::x
real,intent(in)::y
me%x=x
me%y=y
end subroutine point_new
subroutine printSum(me,pp)
class(point),intent(inout)::me
procedure(sub)::pp !任何与子例程sub形参列表相同的子例程都能传入
real::f
me%p=>pp !过程指针确定指向
call me%p(,f) !相当于call me%pp()
write(*,*)'父类sum=',f
end subroutine printSum
end module super_class
module sub_class !子类
use super_class
implicit none
private
type,public,extends(point)::point3d
real::z=0.0
contains
procedure,pass::point3d_new !子类构造函数
end type point3d
contains
subroutine point3d_new(me,x,y,z) !子类构造函数
class(point3d),intent(inout)::me
real,intent(in)::x
real,intent(in)::y
real,intent(in)::z
call me%point%point_new(x,y) !调用父类的构造函数
me%z=z
end subroutine point3d_new
end module sub_class
program main !主程序
use super_class
use sub_class
implicit none
type(point)::a
type(point3d)::b
call a%point_new(1.0,1.0)
call a%printSum(sss)
call b%point3d_new(2.0,2.0,2.0)
call b%printSum(sss)
contains
subroutine sss(me,x,f) !抽象接口具体实现
class(point),intent(inout)::me
real,dimension(:), intent(in)::x
real,intent(out) ::f
f=sum(x)
end subroutine sss
end program main
weixing1531 发表于 2019-8-2 21:25
你的接口是静态方法,子类没有重写父类方法
我的接口是实例方法,子类重写了父类方法,抽象接口作为实例方 ...
个人感觉和重载没有关系,关键在于这是两个文件,而且有private属性,那么sub的定义只在super_class内有效。sub_class模块里的过程printsum是不知道pp的原型是什么的。你可以在sub_class内,把sub的名字改成其他,一样能通过。 lookbook 发表于 2019-8-3 12:32
个人感觉和重载没有关系,关键在于这是两个文件,而且有private属性,那么sub的定义只在super_class内有 ...
若子类成员方法的形参为父类的抽象接口,则父类模块需将其抽象接口公开
若子类模块没有使用父类的抽象接口,则父类模块不必将其抽象接口公开
页:
[1]