zoukankan      html  css  js  c++  java
  • Delphi Interfaces

    http://www.delphibasics.co.uk/Article.asp?Name=Interface 

     

    The reason for interfaces
     

    Classes that extend another class can be called sub-classes.

    For example, you might extend a bicycle class to have mountain bike, and child bike sub-classes.

    They inherit a lot of the common functions of the general bicycle class, but add unique features,

    such as stabilizer wheel options for the child bike.

    You can call bicycle methods, knowing that they apply generally to all types of bicycle.
     

     
     

    This is a traditional, standard use for classes, since the sub-classes are just variations on a theme.

    But supposing you had an application where you had bicycle class objects, car objects, washing machine objects and so on.

    And in this application, you wanted each such class to have the following method:
     

     
     
     function IsRecyclable : Boolean;
     

    that would let you know if the object contained recyclable materials.

    You could define a high-level class containing this method, and define all of the classes from it.

    Or you could simply add the method to each sub class.
     

     
     

    Or you could use interfaces.

    Interfaces simply tidy up this situation.

    By defining an interface that groups these common methods, it sets a standard for all of the classes that implement the interface.

    It makes it easier for the programmer to be disciplined in developing the application;

    all of the classes have an additional set of methods that are identical.

    And Delphi insists that all of the methods in an interface are implemented.
     

     
     

    Going back to the recyclable object scenario, each sub-class inherits common function from its particular parent class.

    This describes the basic structure of the sub-class. It also inherits (by implementation) common function that cut across all classes. 
     

     
     
    An interface example
     

    Like many ideas, an example is the best way to illustrate the concepts.

    We'll do it in stages to keep things as simple as possible.
     

     
      First, let us define a car class:
     
     
     
     type
       // Define our Car class
       TCar = class
       private
         carName  : String;
         carAge   : Byte;
       published
         // Car properties
         property Name : String
           read  carName;
         property Age : Byte
           read  carAge
           write carAge;
     
         // Car constructor
         constructor Create(name : String);
       end;
     

    This class is defined by default based on TObject 

    since we have not specified a base class type.
     

     
      This class has two properties, and a constructor, shown here:
     
     
     
     // Constructor implmentation for the car class
     constructor TCar.Create(name : String);
     begin
       // Save the car name and set default age and miles
       carName  := name;
       carAge   := 0;
     end;
     

    Here we set the two properties of the car : its name and age.

    The name is passed as a parameter, and we set a default age of 0.
     

     
      Now we'll define another class - a bicycle class:
     
     
     
     type
       // Define our Bicycle class
       TBicycle = class
       private
         bikeIsMale    : Boolean;
         bikeWheelSize : Byte;
       published
         // Bicycles properties
         property isMale : Boolean 
           read  bikeIsMale;
         property wheelSize : Byte
           read  bikeWheelSize
           write bikeWheelSize;
     
         // Bicycle constructor
         constructor Create(isMale : Boolean; wheelSize : Byte);
       end;
      This class has two properties, and a constructor, shown here:
     
     
     
     // Constructor implmentation for the bicycle class
     constructor TBicycle.Create(isMale : Boolean; wheelSize : Byte);
     begin
       // Save the passed parameters
       bikeIsMale    := isMale;
       bikeWheelSize := wheelSize;
     end;
     

    This class is a little different from the car class,

    enough to show that we could not have based the car on the bicycle or the bicycle on the car.
     

     
      Now we'll define an interface that says whether a class object is recyclable:
     
     
     
     type
       // An interface definition
       IRecyclable = Interface(IInterface)
         // A single function supporting the property
         function GetIsRecyclable : Boolean;
         // A single property
         property isRecyclable : Boolean read GetIsRecyclable;
       end;
     

    Our interface uses the standard IInterface interface definition as a base.

    Interfaces definitions are like class definitions with all abstract elements.

    We do not have to declare them as abstract - they are by default.
     

     
     

    This interface adds an isRecyclable property to any class that implements it.

    Every class that implements it will have be guaranteed to have exactly the same way of asking if it is recyclable.

    This is the power and benefit of interfaces - uniformity across potentially very different classes.
     

     
      Any class can implement as many interfaces as it wants - it can conform to any global standards in effect.
     
     
     

    Note that we must define the property as using a function -

    we cannot declare a data field in the interface since interfaces do not contain data.
     

     
      Now let us change our classes to support this interface definition:
     
     
     
     type
       // Define our Car class
       TCar = class(TInterfacedObject, IRecyclable)
       private
         carName         : String;
         carAge          : Byte;
         carIsRecyclable : Boolean;    // Added to support IRecyclable
         function GetIsRecyclable : Boolean;   // Added for IRecyclable
       published
         // Car properties
         property Name : String
           read  carName;
         property Age : Byte
           read  carAge
           write carAge;
     
         // Added for IRecyclable
         property isRecyclable : Boolean read GetIsRecyclable;
     
         // Car constructor
         constructor Create(name : String);
       end;
     

    Note that we place the function used by the interface isRecyclable property in the private section

    we only want the caller to use the property. 

     
     

    (Note by author : when compiling the code, Delphi insists on the presence of the GetIsRecyclable function,

    but not on the most important part - the property.

    As far as the author can see, this is not enforcing the salient feature of the interface - the property!).
     

     
     

    We have now based our class on the TInterfaceObject class,

    which provides some standard support for classes that implement interfaces.

    And we have also based our class on IRecyclable, our new interface.
     

     
      But we must also declare the new GetIsRecyclable function:
     
     
     
     // Car function required for IsRecyclable attribute
     function TCar.GetIsRecyclable : Boolean;
     begin
       Result := carIsRecyclable;
     end;
     

    And we must not forget to set this recyclable value.

    We'll do it crudely here in the constructor:
     

     
     
     // Constructor implmentation for the car class
     constructor TCar.Create(name : String);
     begin
       // Save the car name and set default age and miles
       carName         := name;
       carAge          := 0;
       carIsRecyclable := true    // Sets the recyclable indicator
     end;
     

    Phew!

    But we must do the same to the Bicycle class to show the true effect.

    We'll look at complete code defining and using these classes that you can copy and paste into Delphi,

    making note to follow the instructions at the start:
     

     

    // Full Unit code.
     // -----------------------------------------------------------
     // You must store this code in a unit called Unit1 with a form
     // called Form1 that has an OnCreate event called FormCreate.
     
     unit Unit1;
     
     interface
     
     uses
       Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
       Dialogs, DateUtils;
     
     type
        // An interface definition
        IRecyclable = Interface(IInterface)
          // A single function supporting the property
          function GetIsRecyclable : Boolean;
          // A single property
          property isRecyclable : Boolean read GetIsRecyclable;
        end;
     
       // Define our Car class
       TCar = class(TInterfacedObject, IRecyclable)
       private
         carName  : String;
         carAge   : Byte;
         carIsRecyclable : Boolean;
         function GetIsRecyclable : Boolean;   // Added for IRecyclable
       published
         // Car properties
         property Name : String
           read  carName;
         property Age : Byte
           read  carAge
           write carAge;
     
         // Added for IRecyclable
         property isRecyclable : Boolean read GetIsRecyclable;
     
         // Car constructor
         constructor Create(name : String);
       end;
     
       // Define our Bicycle class
       TBicycle = class(TInterfacedObject, IRecyclable)
       private
         bikeIsMale       : Boolean;
         bikeWheelSize    : Byte;
         function GetIsRecyclable : Boolean;   // Added for IRecyclable
       published
         // Bicycles properties
         property isMale : Boolean
           read  bikeIsMale;
         property wheelSize : Byte
           read  bikeWheelSize
           write bikeWheelSize;
     
         // Added for IRecyclable
         property isRecyclable : Boolean read GetIsRecyclable;
     
         // Bicycle constructor
         constructor Create(isMale : Boolean; wheelSize : Byte);
       end;
     
       // The definition of the program form
       TForm1 = class(TForm)
         procedure FormCreate(Sender: TObject);
       private
         { private declarations }
       public
         { public declarations }
       end;
     
     var
       Form1: TForm1;
     
     implementation
     
     {$R *.dfm}
     
     // Constructor implmentation for the car class
     constructor TCar.Create(name : String);
     begin
       // Save the car name and set default age and miles
       carName         := name;
       carAge          := 0;
       carIsRecyclable :=true    // Sets the recyclable indicator
     end;
     
     // Car function required for IsRecyclable attribute
     function TCar.GetIsRecyclable : Boolean;
     begin
       Result := carIsRecyclable;
     end;
     
     // Constructor implmentation for the bicycle class
     constructor TBicycle.Create(isMale : Boolean; wheelSize : Byte);
     begin
       // Save the passed parameters
       bikeIsMale    := isMale;
       bikeWheelSize := wheelSize;
     end;
     
     // Bicycle function required for IsRecyclable attribute
     function TBicycle.GetIsRecyclable : Boolean;
     begin
       // We'll asy that only male bicycles are recyclable
       if self.isMale
       then Result := true
       else Result := false;
     end;
     
     procedure TForm1.FormCreate(Sender: TObject);
     var
       mumsBike : TBicycle;
       dadsCar  : TCar;
     begin
       // Instantiate our bike and car objects
       mumsBike := TBicycle.Create(false, 24);
       dadsCar  := TCar.Create('Nissan bluebird');
     
       // Ask if each is recyclable
       if dadsCar.isRecyclable
       then ShowMessage('Dads car is recyclable')
       else ShowMessage('Dads car is not recyclable');
     
       if mumsBike.isRecyclable
       then ShowMessage('Mums bike is recyclable')
       else ShowMessage('Mums bike is not recyclable');
     end;
     
     end.
     The ShowMessage shows the following program output:
     Dads car is recyclable
     Mums bike is not recyclable
  • 相关阅读:
    冒泡排序
    数据结构和算法关系
    js获取ifram对象
    java STL
    bufferedReader 乱码问题
    css animation让图标不断旋转
    apply通过实例理解
    jquery.ajaxfileupload.js
    JDBC getMetaData将结果集组装到List
    Android开发之使用BaseAdapter的notifyDataSetChanged()无法更新列表
  • 原文地址:https://www.cnblogs.com/shangdawei/p/3983202.html
Copyright © 2011-2022 走看看