转至繁体中文版     | 网站首页 | 图文教程 | 资源下载 | 站长博客 | 图片素材 | 武汉seo | 武汉网站优化 | 
最新公告:     敏韬网|教学资源学习资料永久免费分享站!  [mintao  2008年9月2日]        
您现在的位置: 学习笔记 >> 图文教程 >> 软件开发 >> Delphi程序 >> 正文
The Delphi Object Model (PART I)         ★★★★

The Delphi Object Model (PART I)

作者:闵涛 文章来源:闵涛的学习笔记 点击数:3306 更新时间:2009/4/23 18:43:49
chapter). As in Java, but not C++, every class inherits from a single root class, TObject. If you do not specify an explicit base class, Delphi automatically uses TObject as the base class.

TIP:
A base class is a class''''s immediate parent class, which you can see in the class declaration. An ancestor class is the base class or any other class in the inheritance chain up to TObject. Thus, in Example 2-1, TCertificateOfDeposit has a base class of TSavingsAccount; its ancestor classes are TObject, TAccount, and TSavingsAccount.

The TObject class declares several methods and one special, hidden field to store a reference to the object''''s class. This hidden field points to the class''''s virtual method table (VMT). Every class has a unique VMT and all objects of that class share the class''''s VMT. Chapter 5, Language Reference, covers the other details of the TObject class and its methods.

You can assign an object reference to a variable whose type is the object''''s class or any of its ancestor classes. In other words, the declared type of an object reference is not necessarily the same as the actual type of the object. Assignments that go the other way--assigning a base-class object reference to a derived-class variable--are not allowed because the object might not be of the correct type.

Delphi retains the strong type-checking of Pascal, so the compiler performs compile-time checks based on the declared type of an object reference. Thus, all methods must be part of the declared class, and the compiler performs the usual checking of function and procedure arguments. The compiler does not necessarily bind the method call to a specific method implementation. If the method is virtual, Delphi waits until runtime and uses the object''''s true type to determine which method implementation to call. See the section "Methods," later in this chapter for details.

Use the is operator to test the object''''s true class. It returns True if the class reference is the object''''s class or any of its ancestor classes. It returns False if the object reference is nil or of the wrong type. For example:

if Account is TCheckingAccount then ... // tests the class of Account if Account is TObject then ... // True when Account is not nil

You can also use a type cast to obtain an object reference with a different type. A type cast does not change an object; it just gives you a new object reference. Usually, you should use the as operator for type casts. The as operator automatically checks the object''''s type and raises a runtime error if the object''''s class is not a descendant of the target class. (The SysUtils unit maps the runtime error to an EInvalidCast exception.)

Another way to cast an object reference is to use the name of the target class in a conventional type cast, similar to a function call. This style of type cast does not check that the cast is valid, so use it only if you know it is safe, as shown in Example 2-3.

Example 2-3: Using Static Type Casts

var
  Account: TAccount;
  Checking: TCheckingAccount;
begin
  Account  := Checking;                    // Allowed
  Checking := Account;                     // Compile-time error
  Checking := Account as TCheckingAccount; // Okay
  Account as TForm;                        // Raises a runtime error
  Checking := TCheckingAccount(Account);   // Okay, but not recommended
  if Account is TCheckingAccount then      // Better
    Checking := TCheckingAccount(Account)
  else
    Checking := nil;

Fields

A field is a variable that is part of an object. A class can declare any number of fields, and each object has its own copy of every field declared in its class and in every ancestor class. In other languages, a field might be called a data member, an instance variable, or an attribute. Delphi does not have class variables, class instance variables, static data members, or the equivalent (that is, variables that are shared among all objects of the same class). Instead, you can usually use unit-level variables for a similar effect.

A field can be of any type unless the field is published. In a published section, a field must have a class type, and the class must have runtime type information (that is, the class or an ancestor class must use the $M+ directive). See Chapter 3 for more information.

When Delphi first creates an object, all of the fields start out empty, that is, pointers are initialized to nil, strings and dynamic arrays are empty, numbers have the value zero, Boolean fields are False, and Variants are set to Unassigned. (See NewInstance and InitInstance in Chapter 5 for details.)

A derived class can declare a field with the same name as a field in an ancestor class. The derived class''''s field hides the field of the same name in the ancestor class. Methods in the derived class refer to the derived class''''s field, and methods in the ancestor class refer to the ancestor''''s field.

Methods

Methods are functions and procedures that apply only to objects of a particular class and its descendants. In C++, methods are called "member functions." Methods differ from ordinary procedures and functions in that every method has an implicit parameter called Self, which refers to the object that is the subject of the method call. Self is similar to this in C++ and Java. Call a method the same way you would call a function or procedure, but preface the method name with an object reference, for example:

Object.Method(Argument);

A class method applies to a class and its descendants. In a class method, Self refers not to an object but to the class. The C++ term for a class method is "static member function."

You can call a method that is declared in an object''''s class or in any of its ancestor classes. If the same method is declared in an ancestor class and in a derived class, Delphi calls the most-derived method, as shown in Example 2-4.

Example 2-4: Binding Static Methods

type
  TAccount = class
  public
    procedure Withdraw(Amount: Currency);
  end;
  TSavingsAccount = class(TAccount)
  public
    procedure Withdraw(Amount: Currency);
  end;
var
  Savings: TSavingsAccount;
  Account: TAccount;
begin
  ...
  Savings.Withdraw(1000.00);     // Calls TSavingsAccount.Withdraw
  Account.Withdraw(1000.00);     // Calls TAccount.Withdraw

An ordinary method is called a static method because the compiler binds the method call directly to a method implementation. In other words, the binding is static. In C++ this is an ordinary member function, and in Java it''''s called a "final method." Most Delphi programmers refrain from using the term static method, preferring the simple term, method or even non-virtual method.

A virtual method is a method that is bound at runtime instead of at compile time. At compile time, Delphi uses the declared type of an object reference to determine which methods you are allowed to call. Instead of compiling a direct reference to any specific method, the compiler stores an indirect method reference that depends on the object''''s actual class. At runtime, Delphi looks up the method in the class''''s runtime tables (specifically, the VMT), and calls the method for the actual class. The object''''s true class might be the compile-time declared class, or it might be a derived class--it doesn''''t matter because the VMT provides the pointer to the correct method.

To declare a virtual method, use the virtual directive in the base class, and use the override directive to provide a new definition of the method in a derived class. Unlike in Java, methods are static by default, and you must use the virtual directive to declare a virtual method. Unlike in C++, you must use the override directive to override a virtual method in a derived class.

Example 2-5 uses virtual methods.

Example 2-5: Binding Virtual Methods

type
  TAccount = class
  public
    procedure Withdraw(Amount: Currency); virtual;
  end;
  TSavingsAccount = class(TAccount)
  public
    procedure Withdraw(Amount: Currency); override;
  end;
var
  Savings: TSavingsAccount;
  Account: TAccount;
begin
  ...
  Savings.Withdraw(1000.00);     // Calls TSavingsAccount.Withdraw
  Account := Savings;
  Account.Withdraw(1000.00);     // Calls TSavingsAccount.Withdraw

Instead of using the virtual directive, you can also use the dynamic directive. The semantics are identical, but the implementation is different. Looking up a virtual method in a VMT is fast because the compiler generates an index directly into a VMT. Looking up a dynamic method is slower. Calling a dynamic method requires a linear search of a class''''s dynamic method table (DMT). If the class does not override that method, the search continues with the DMT of the base class. The search continues with ancestor classes until TObject is reached or the method is found. The tradeoff is that in a few circumstances, dynamic methods take up less memory than virtual methods. Unless you are writing a replacement for the VCL, you should use virtual methods, not dynamic methods. See Chapter 3 for a complete explanation of how dynamic and virtual methods are implemented.

A virtual or dynamic method can be declared with the abstract directive, in which case the class does not define the method. Instead, der

上一页  [1] [2] [3] [4] [5]  下一页


[系统软件]InstallShield Express for delphi制作安装程序定…  [系统软件]The GRETA Regular Expression Template Archive
[系统软件]OLE with the internet explorer  [系统软件]14.5.10.1 Object creation expressions
[常用软件]InstallShield Express制作Delphi数据库安装程序  [常用软件]Firefox: What’s the next step?
[VB.NET程序]VB.Net中文教程(8)  对象(Object)基本概念  [VB.NET程序]The UDPChat Source(VB.NET)
[Delphi程序]为什么选择Delphi.Net ?  [Delphi程序]《关于VisiBroker For Delphi的使用》(4)
教程录入:mintao    责任编辑:mintao 
  • 上一篇教程:

  • 下一篇教程:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      注:本站部分文章源于互联网,版权归原作者所有!如有侵权,请原作者与本站联系,本站将立即删除! 本站文章除特别注明外均可转载,但需注明出处! [MinTao学以致用网]
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)

    同类栏目
    · C语言系列  · VB.NET程序
    · JAVA开发  · Delphi程序
    · 脚本语言
    更多内容
    热门推荐 更多内容
  • 没有教程
  • 赞助链接
    更多内容
    闵涛博文 更多关于武汉SEO的内容
    500 - 内部服务器错误。

    500 - 内部服务器错误。

    您查找的资源存在问题,因而无法显示。

    | 设为首页 |加入收藏 | 联系站长 | 友情链接 | 版权申明 | 广告服务
    MinTao学以致用网

    Copyright @ 2007-2012 敏韬网(敏而好学,文韬武略--MinTao.Net)(学习笔记) Inc All Rights Reserved.
    闵涛 投放广告、内容合作请Q我! E_mail:admin@mintao.net(欢迎提供学习资源)

    站长:MinTao ICP备案号:鄂ICP备11006601号-18

    闵涛站盟:医药大全-武穴网A打造BCD……
    咸宁网络警察报警平台