MODULE CLASS_CIRCLE
    IMPLICIT NONE
    PRIVATE
    PUBLIC :: CIRCLE, CIRCLE_AREA, CIRCLE_PRINT

    REAL :: PI = 3.1415926535897931d0 ! Class-wide private constant

    TYPE, PUBLIC :: CIRCLE
        REAL :: RADIUS
        CONTAINS
            PROCEDURE :: AREA => CIRCLE_AREA
            PROCEDURE :: PRINT => CIRCLE_PRINT
    END TYPE CIRCLE

CONTAINS

    FUNCTION CIRCLE_AREA(THIS) RESULT(AREA)
        CLASS(CIRCLE), INTENT(IN) :: THIS
        REAL :: AREA
        AREA = PI * THIS%RADIUS**2.0
    END FUNCTION CIRCLE_AREA

    SUBROUTINE CIRCLE_PRINT(THIS)
        CLASS(CIRCLE), INTENT(IN) :: THIS
        REAL :: AREA
        AREA = THIS%AREA()    ! Call the type_bound function
        PRINT *, 'Circle: r = ', this%radius, ' area = ', AREA
    END SUBROUTINE CIRCLE_PRINT
END MODULE CLASS_CIRCLE

PROGRAM CIRCLE_TEST
    USE CLASS_CIRCLE
    IMPLICIT NONE

    TYPE(CIRCLE) :: C ! Declare a variable of type Circle.
    C = CIRCLE(1.5)   ! Use the implicit constructor, radius = 1.5
    CALL C%PRINT      ! Call a type-bound subroutine

END PROGRAM CIRCLE_TEST