我对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.
答案 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包。
这三个都不可能。