定义接口

From Apache OpenOffice Wiki
< Zh‎ | Documentation
Revision as of 09:29, 21 July 2008 by Jirong (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search


接口可以描述对象的各个方面。要为组件指定新行为,应该从定义由提供新行为的方法组成的接口 开始。使用 attribute 指令在一个步骤中定义一对无格式的 get 和 set 方法。或者,您也可以使用 任意参数和异常定义自己的操作,方法是编写方法签名以及操作抛出的异常。我们将首先使用 attribute 指令编写一个小的接口定义,然后考虑使用 XUNoUrlResolver 中的 resolve() 方法。

Interfaces describe aspects of objects. To specify a new behavior for the component, start with an interface definition that comprises the methods offering the new behavior. Define a pair of plain get and set methods in a single step using the attribute instruction. Alternatively, choose to define your own operations with arbitrary arguments and exceptions by writing the method signature, and the exceptions the operation throws. We will first write a small interface definition with attribute instructions, then consider the resolve() method in XUNoUrlResolver.


假设我们要在 OpenOffice.org 发布一个 ImageShrink 组件,以便创建要在 StarSuite 表格中使用的 缩略图图像。现在,已有一个 com.sun.star.document.XFilter 接口可以提供支持文件转换的方 法。此外,还需要一个方法以获取和设定源目录和目标目录以及要创建的缩略图的大小。通常服务 及其主要接口都有对应的名称,因此我们的组件应该包括一个带有通过 get 和 set 操作可实现此目的 的 org::openoffice::test::XImageShrink 接口。

Let us assume we want to contribute an ImageShrink component to OpenOffice.org to create thumbnail images for use in OpenOffice.org tables. There is already a com.sun.star.document.XFilter interface offering methods supporting file conversion. In addition, a method is required to get and set the source and target directories, and the size of the thumbnails to create. It is common practice that a service and its prime interface have corresponding names, so our component shall have an org::openoffice::test::XImageShrink interface with methods to do so through get and set operations.



属性

attribute 指令可以为试验接口定义创建以下操作:

The attribute instruction creates these operations for the experimental interface definition:

请参阅 XImageShrink 接口的规范 1: Look at the specification for our XImageShrink interface:

  #ifndef __org_openoffice_test_XImageShrink_idl__
  #define __org_openoffice_test_XImageShrink_idl__
  #include <com/sun/star/uno/XInterface.idl>
  #include <com/sun/star/awt/Size.idl>
 
  module org { module openoffice { module test {
 
  interface XImageShrink : com::sun::star::uno::XInterface 
  {
      [attribute] string SourceDirectory;
      [attribute] string DestinationDirectory;
      [attribute] com::sun::star::awt::Size Dimension;
  };
 
  }; }; };
 
  #endif

我们使用 #ifndef 防止接口被重新定义,然后添加 #include com.sun.star.uno.XInterface 和结构 com.sun.star.awt.Size。这些可以通过全局索引在 API 引用中找到。我们的接口在 org::openoffice::test 模块中将是已知的,因此它可以嵌套在对应的 module 指令中。

We protect the interface from being redefined using #ifndef, then added #include com.sun.star.uno.XInterface and the struct com.sun.star.awt.Size. These were found in the API reference using its global index. Our interface will be known in the org::openoffice::test module, so it is nested in the corresponding module instructions.


使用 interface 指令定义接口。该指令的开头是关键字 interface,然后给出接口名称并从父接口(也称为超级接口)导出新接口。之后在花括号中定义接口的主体。interface 指令以分号结尾。


在本示例中,引入的接口是 XImageShrink<、code>。按照惯例,所有接口的标识符都以 X 开头。每个接口都必须从所有 UNO 接口的基接口 <code>XInterface<、code> 继承,或者从这个接口的一个导出接口中继承。简单的单一继承用冒号 <code>:<、code> 表示,冒号之后是父类型的全限定名称。UNOIDL 类型的全限定名称是其标识符,包括所有包含模块,模块之间用范围运算符 <code>:: 分隔。这里我们直接从 com::sun::star::uno::XInterface<、code> 导出所需的接口。如果需要声明一个从多个接口继承的新接口,请勿使用冒号,而是在新接口主体中列出所有继承的接口:

  interface XMultipleInheritance {
     interface XBase1;
      interface XBase2;
  };
Documentation caution.png UNOIDL 允许传送用作参数、返回值或结构成员的接口声明。但是,要从中导出其他接口的接口必须是完全定义的接口。


超级接口之后是接口的主体。它包含属性和方法声明,在多继承接口的情况下还包含被继承接口的声明。请注意 <code>XImageShrink
接口的主体。它包含三个属性,但不包含方法。下面将讨论这些接口方法。


attribute 声明的开头是用方括号括起的关键字 attribute,然后给出已知类型和该属性的标识符,结尾是分号。


我们的示例中定义了名为 SourceDirectoryDestinationDirectorystring 属性以及已知为 Dimensioncom::sun::star::awt::Size 属性:

  [attribute] string SourceDirectory;
  [attribute] string DestinationDirectory;
  [attribute] com::sun::star::awt::Size Dimension;

在 Java 和 C++ 代码生成期间,attribute 声明将引出 get 和 set 方法对。例如,从此类型说明中由 javamaker 生成的Java 接口包含以下六个方法:

  // from attribute SourceDir
  public String getSourceDirectory();
  public void setSourceDirectory(String _sourcedir);
 
  // from attribute DestinationDir
  public String getDestinationDirectory();
  public void setDestinationDirectory(String _destinationdir);
 
  // from attribute Dimension
  public com.sun.star.awt.Size getDimension();
  public void setDimension(com.sun.star.awt.Size _dimension);


另外还可以定义:属性不能使用 readonly<、code> 标志从外部进行更改。要设定此标志,请编写 <code>[attribute, readonly]<、code>。其结果是在代码生成期间只创建 <code>get()<、code> 方法,而不创建 <code>set()<、code> 方法。另外一个选择是将属性标记为 bound;当接口属性映射为属性时此标志将非常有用,请参阅 编写 UNO 组件 - Java 中的简单组件 - 存储服务管理器已备后用编写 UNO 组件 - C++ 组件


从 OpenOffice.org 2.0 开始,属性可以分别针对获取和设置属性的操作规定异常规范:

  [attribute] long Age { 
      get raises (DatabaseException); // raised when retrieving the age from the database fails
      set raises (IllegalArgumentException, // raised when the new age is negative
                  DatabaseException); // raised when storing the new age in the database fails
  };


如果没有给出异常规范,可能只会抛出运行时异常。



方法

编写真正的组件时,通过提供方法的签名以及在 idl 文件中抛出的异常来定义方法。上面的 <code>XUnoUrlResolver 示例介绍了 resolve() 方法,该方法接受 UNO URL 并抛出三个异常。

  interface XUnoUrlResolver: com::sun::star::uno::XInterface
  { 
      com::sun::star::uno::XInterface resolve( [in] string sUnoUrl ) 
          raises (com::sun::star::connection::NoConnectException, 
                    com::sun::star::connection::ConnectionSetupException, 
                    com::sun::star::lang::IllegalArgumentException); 
  };


方法的基本结构类似于 C++ 函数或 Java 方法。定义方法时要给出已知的返回类型、操作名称和参数(括号 () 括起),如果有必要,还要给出该方法可能抛出的异常。参数列表、异常子句 raises()<、code> 以及操作前的可选 <code>[oneway]<、code> 标志在 UNOIDL 中很特殊。


  • 参数列表中的每个参数必须以一个方向标志 <code>[in][out][inout] 开始,然后给出参数的已知类型和标识符。方向标志用于指定操作使用参数的方式:
方法的方向标志 说明
in 指定方法将参数作为输入参数,但不会进行更改。
out 指定参数不参数化方法,而是方法将参数作为输出参数。
inout 指定操作由参数进行参数化,而且方法也将参数用作输出参数。
  • 尽量避免使用 [ inout ][ out ] 限定符,因为在特定语言绑定(如 Java 语言绑定)中很难处理这些限定符。参数列表可以为空。如果包含多个参数,则参数之间必须用逗号分隔。
  • 异常通过可选的 raises () 子句给出,子句中包含逗号分隔的异常列表,异常用全名给出。raises () 子句表示只有列出的异常,即 com.sun.star.uno.RuntimeException 及其下代可以由实现抛出。通过指定方法的异常,您的接口的实现程序可以将信息返回给调用程序,从而避免可能的错误状况。


如果预先挂起操作的 [ oneway ] 标志,且基础方法调用系统支持此功能,则可以异步执行该操作。例如,UNO 远程协议 (URP) 桥就是一个支持单向调用的系统。[ oneway ] 操作不可能具有返回值,也不可能具有 out 或 inout 参数。只能抛出 com.sun.star.uno.RuntimeException 异常。


Documentation caution.png 尽管 UNO 单向调用功能的规范和实现没有出现常规问题,但在几种 API 远程使用方案中,单向调用仍会导致 OpenOffice.org 中发生死锁。因此,建议您不要使用新的 StarSuite UNO API 引入新的 oneway 方法。
Documentation caution.png 您不能覆盖从父接口继承的属性或方法,因为这在抽象的规范中是毫无意义的。而且,过载也是不可的。限定的接口标识符以及方法名称共同构成了唯一的方法名称。
Content on this page is licensed under the Public Documentation License (PDL).
Personal tools
In other languages