RAD Studio |  |

Using the object model
Collapse All
Topics

Name | Description
Using Object Variables | You can assign one object variable to another object variable if the variables are of the same type or are assignment compatible. In particular, you can assign an object variable to another object variable if the type of the variable to which you are assigning is an ancestor of the type of the variable being assigned. For example, here is a TSimpleForm type declaration and a variable declaration section declaring two variables, AForm and Simple:
Changing the Name of a Component | You should always use the Object Inspector to change the name of a component. For example, suppose you want to change a form's name from the default Form1 to a more descriptive name, such as ColorWindow. When you change the form's Name property in the Object Inspector, the new name is automatically reflected in the form's .dfm or .xfm file (which you usually don't edit manually) and in the source code that the IDE generates:
Components and Ownership | Delphi components have a built-in memory-management mechanism that allows one component to assume responsibility for freeing another. The former component is said to own the latter. The memory for an owned component is automatically freed when its owner's memory is freed. The owner of a component—the value of its Owner property—is determined by a parameter passed to the constructor when the component is created. By default, a form owns all components on it and is in turn owned by the application. Thus, when the application shuts down, the memory for all forms and the components on them is freed. Ownership... more
Creating, Instantiating, and Destroying Objects | Many of the objects you use in the Form Designer, such as buttons and edit boxes, are visible at both design time and runtime. Some, such as common dialog boxes, appear only at runtime. Still others, such as timers and data source components, have no visual representation at runtime. You may want to create your own classes. For example, you could create a TEmployee class that contains Name, Title, and HourlyPayRate properties. You could then add a CalculatePay method that uses the data in HourlyPayRate to compute a paycheck amount. The TEmployee type declaration might look like this:... more
Examining a Delphi Object | When you create a new project, the IDE displays a new form for you to customize. In the Code editor, the automatically generated unit declares a new class type for the form and includes the code that creates the new form instance. The generated code for a new Windows application looks like this:
Inheriting Data and Code from an Object | The TForm1 object in examining a Delphi object seems simple. TForm1 appears to contain one field (Button1), one method (Button1Click), and no properties. Yet you can show, hide, or resize of the form, add or delete standard border icons, and set up the form to become part of a Multiple Document Interface (MDI) application. You can do these things because the form has inherited all the properties and methods of the component TForm. When you add a new form to your project, you start with TForm and customize it by adding components, changing property values,... more
Private, Protected, Public, and Published Declarations | A class type declaration contains three or four possible sections that control the accessibility of its fields and methods:
Scope and Qualifiers | Scope determines the accessibility of an object's fields, properties, and methods. All members declared in a class are available to that class and, as is discussed later, often to its descendants. Although a method's implementation code appears outside of the class declaration, the method is still within the scope of the class because it is declared in the class declaration. When you write code to implement a method that refers to properties, methods, or fields of the class where the method is declared, you don't need to preface those identifiers with the name of the class. For example, if you... more
Using the Object Model | The Delphi language is a set of object-oriented extensions to standard Pascal. Object-oriented programming is an extension of structured programming that emphasizes code reuse and encapsulation of data with functionality. Once you define a class, you and other programmers can use it in different applications, thus reducing development time and increasing productivity. The following topics provide a brief introduction to object-oriented concepts for programmers who are just starting out with the Delphi language. For more details on object-oriented programming for programmers who want to write components that can be installed on the Tool palette, see Overview of Component Creation... more
What Is an Object? | A class is a data type that encapsulates data and operations on data in a single unit. Before object-oriented programming, data and operations (functions) were treated as separate elements. An object is an instance of a class. That is, it is a value whose type is a class. The term object is often used more loosely in this documentation and where the distinction between a class and an instance of the class is not important, the term "object" may also refer to a class. You can begin to understand objects if you understand Pascal records or structures in C. Records... more
TInterfacedObject | When defining a class that supports one or more interfaces, it is convenient to use TInterfacedObject as a base class because it implements the methods of IInterface. TInterfacedObject class is declared in the System unit as follows:
Defining New Classes (Delphi) | Although there are many classes in the object hierarchy, you are likely to need to create additional classes if you are writing object-oriented programs. The classes you write must descend from TObject or one of its descendants. The advantage of using classes comes from being able to create new classes as descendants of existing ones. Each descendant class inherits the fields and methods of its parent and ancestor classes. You can also declare methods in the new class that override inherited ones, introducing new, more specialized behavior. The general syntax of a descendant class is as follows:
Aggregation | Aggregation offers a modular approach to code reuse through sub-objects that make up the functionality of a containing object, but that hide the implementation details from that object. In aggregation, an outer object implements one or more interfaces. At a minimum, it must implement IInterface. The inner object, or objects, also implement one or more interfaces. However, only the outer object exposes the interfaces. That is, the outer object exposes both the interfaces it implements and the ones that its contained objects implement. Clients know nothing about inner objects. While the outer object provides access to the inner object... more
Implementing IInterface | Just as all objects descend, directly or indirectly, from TObject, all interfaces derive from the IInterface interface. IInterface provides for dynamic querying and lifetime management of the interface. This is established in the three IInterface methods: QueryInterface dynamically queries a given object to obtain interface references for the interfaces that the object supports. _AddRef is a reference counting method that increments the count each time a call to QueryInterface succeeds. While the reference count is nonzero the object must remain in memory. _Release is used with _AddRef to allow an object to track its own lifetime and determine when... more
Memory Management of Interface Objects | One of the concepts behind the design of interfaces is ensuring the lifetime management of the objects that implement them. The _AddRef and _Release methods of IInterface provide a way to implement this lifetime management. _AddRef and _Release track the lifetime of an object by incrementing the reference count on the object when an interface reference is passed to a client, and will destroy the object when that reference count is zero. If you are creating COM objects for distributed applications (in the Windows environment only), then you should strictly adhere to the reference counting rules. However, if you are... more
Not Using Reference Counting | If your object is a component or a control that is owned by another component, then it is part of a different memory management system that is based in TComponent. Although some classes mix the object lifetime management approaches of TComponent and interface reference counting, this is very tricky to implement correctly. To create a component that supports interfaces but bypasses the interface reference counting mechanism, you must implement the _AddRef and _Release methods in code such as the following:
Reusing Code and Delegation | One approach to reusing code with interfaces is to have one interfaced object contain, or be contained by another. Using properties that are object types provides an approach to containment and code reuse. To support this design for interfaces, the Delphi language has a keyword implements, that makes if easy to write code to delegate all or part of the implementation of an interface to a subobject. Aggregation is another way of reusing code through containment and delegation. In aggregation, an outer object uses an inner object that implements interfaces which are exposed only by the outer object.
Using Interfaces Across the Hierarchy | Using interfaces lets you separate the way a class is used from the way it is implemented. Two classes can implement the same interface without descending from the same base class. By obtaining an interface from either class, you can call the same methods without having to know the type of the class. This polymorphic use of the same methods on unrelated objects is possible because the objects implement the same interface. For example, consider the interface,
Using Implements for Delegation | Many classes have properties that are subobjects. You can also use interfaces as property types. When a property is of an interface type (or a class type that implements the methods of an interface) you can use the keyword implements to specify that the methods of that interface are delegated to the object or interface reference which is the value of the property. The delegate only needs to provide implementation for the methods. It does not have to declare the interface support. The class containing the property must include the interface in its ancestor list. By default, using the implements... more
Using Interfaces | Delphi is a single-inheritance language. That means that any class has only a single direct ancestor. However, there are times you want a new class to inherit properties and methods from more than one base class so that you can use it sometimes like one and sometimes like the other. Interfaces let you achieve something like this effect. An interface is like a class that contains only abstract methods (methods with no implementation) and a clear definition of their functionality. Interface method definitions include the number and types of their parameters, their return type, and their expected behavior. By convention,... more
Using Interfaces in Distributed Applications | In VCL applications, interfaces are a fundamental element in the COM and SOAP distributed object models. Delphi provides base classes for these technologies that extend the basic interface functionality in TInterfacedObject, which simply implements the IInterface interface methods. When using COM, classes and interfaces are defined in terms of IUnknown rather than IInterface. There is no semantic difference between IUnknown and IInterface, the use of IUnknown is simply a way to adapt Delphi interfaces to the COM definition. COM classes add functionality for using class factories and class identifiers (CLSIDs). Class factories are responsible for creating class... more
Using Interfaces with Procedures | Interfaces allow you to write generic procedures that can handle objects without requiring that the objects descend from a particular base class. Using the IPaint and IRotate interfaces defined previously, you can write the following procedures:
Using Reference Counting | The Delphi compiler provides most of the IInterface memory management for you by its implementation of interface querying and reference counting. Therefore, if you have an object that lives and dies by its interfaces, you can easily use reference counting by deriving from TInterfacedObject. If you decide to use reference counting, then you must be careful to only hold the object as an interface reference, and to be consistent in your reference counting. For example:
Using the as Operator with Interfaces | Classes that implement interfaces can use the as operator for dynamic binding on the interface. In the following example,

Copyright(C) 2009 Embarcadero Technologies, Inc. All Rights Reserved.
What do you think about this topic? Send feedback!