PL / SQL私有对象方法

时间:2009-10-16 20:23:45

标签: sql oracle plsql oracle10g

我对Oracle的PL / SQL(使用10g)有点新手,我想知道是否有办法在对象类型中创建私有方法,就像其他语言中的私有帮助器方法一样(Java, C ++,C#等......)。我知道可以在包中创建私有方法,但我似乎无法找到对象类型执行此操作的方法。我不断收到编译错误告诉我:

Error: PLS-00539: subprogram 'FOO' is declared in an object type body 
and must be defined in the object type specification.

3 个答案:

答案 0 :(得分:2)

好的,这是一个我非常简短地测试的潜在解决方案,到目前为止似乎有效:

创建一个标记为NOT FINAL且NOT INSTANTIABLE的父对象类型,然后将所有私有代码放在那里。私有方法不是真正的私有方法,但是将它们放在一个非final和不可实例化的类型中会阻止它们被调用。在可实例化的子类型中,通过SELF引用超类型中的“私有”方法。 例如:


create or replace type PrivateFoo under SuperFoo
(

  member procedure setUpCommonFoo
) NOT INSTANTIABLE NOT FINAL;

create or replace type body PrivateFoo is
  -- Member procedures and functions
  member procedure setUpCommonFoo is
        begin
            SELF.someAttrib:='Some Common Default Value';
        end;
end;

create or replace type Foo under PrivateFoo
(
    CONSTRUCTOR FUNCTION Foo RETURN SELF AS RESULT,
    CONSTRUCTOR FUNCTION Foo(fkey FooKey) RETURN SELF AS RESULT -- assume fkey is defined in SuperFoo, and FooKey type is defined somewhere else ;)
)

create or replace type body Foo is
    --no-arg Constructor For basic Foo set up.
    CONSTRUCTOR FUNCTION PartyConvertor RETURN SELF AS RESULT AS
    BEGIN
        self.setUpCommonFoo;
        RETURN;
    END;
        --alt constructor for other situations...
    CONSTRUCTOR FUNCTION PartyConvertor(fkey FooKey) RETURN SELF AS RESULT AS
    BEGIN
        self.setUpCommonFoo;
                SELF.rarelyUsedAttrib:='Special Value!'; --just assume that someAttrib and rarelyUsedAttrib actually exist ;)
        self.fkey := fkey;
        RETURN;
    END;
        --Other Members go here...
end;

现在我不得不承认,我真的不喜欢这种模式。这看起来很尴尬和笨拙。我可能会尽可能地避免对象类型并坚持使用包(或非常类似于对象类型)。 package-as-fatory只能帮助我解决构造函数的私有公共代码问题,而不是其他类型的公共代码重构。

...除非有更好的方式使用对象类型......任何人?任何人吗?

答案 1 :(得分:2)

如果您只需要使用一个子程序中的子程序(函数/过程)PL / SQL允许您在声明块中将子程序嵌套在另一个子程序中。

它不像拥有私有方法或函数那样理想,但在创建继承层次结构之前可能值得一试。

create or replace type body some_t
as

member function foo
    return varchar2
    as
        function some_private_foo
            return varchar2
            as
            begin
                return 'Foo!';
            end some_private_foo;
    begin
        return some_private_foo();
    end foo;

end;

如果您使用的是Oracle 12,那么您很幸运。您可以使用ACCESSIBLE BY子句创建只有您的类型可以编码的包。在下面的示例中,PL / SQL编译器仅允许来自FOO_T的代码引用FOO_PRIVATE_PKG。

CREATE OR REPLACE package foo_private_pkg 
accessible by ( foo_t )
as

function some_private_foo ( object_in in out nocopy foo_t )
    return varchar2;
end;

答案 2 :(得分:1)

你不能在pl / sql对象中拥有私有方法,你可以拥有多态和继承但没有封装。

如果需要封装(私有方法),可以使用pl / sql包。

这三个都不可能。