ColdFusion でのオブジェクト指向プログラミング

ColdFusion のコンポーネントについては、ColdFusion のコンポーネントの作成と使用を参照してください。

ColdFusion の OOP の新機能と強化機能について詳しくは、以下を参照してください。

抽象コンポーネントと抽象メソッド

抽象コンポーネントには、body のない抽象メソッドや、実装のあるメソッドを含めることができます。

抽象コンポーネントや抽象メソッドを作成するには、abstract キーワードを使用します。ColdFusion では、抽象コンポーネントをインスタンス化できません。抽象コンポーネントは、多くの場合、サブコンポーネントのベースを提供するために使用されます。最初の実体コンポーネントの継承階層に、すべての抽象メソッドの実装を含める必要があります。

注意:

実体コンポーネントに抽象メソッドを含めることはできません。

抽象コンポーネントを宣言するには、次のようにします。

// myAbstractClass.cfc
abstract component {
 // abstract methods
 // concrete methods
}

以上が、ColdFusion で抽象コンポーネントを宣言する方法です。

myAbstractClass のインスタンスを作成することはできません。そのため、次のコードは有効ではありません

myClassInstance=new myAbstractComponent();

ColdFusion で抽象コンポーネントを使用する例を次に示します。

Shape.cfc

abstract component Shape{
 abstract function draw();
} 

Square.cfc

component Square extends="Shape" {
 function draw() {
      writeoutput("Inside Square::draw() method. <br/>");
   }
}

ShapeFactory.cfc

component ShapeFactory extends="AbstractFactory" {
 
 Shape function getShape(String shapeType){
   
       if(shapeType EQ "RECTANGLE"){
         return new Rectangle();
         
      }else if(shapeType EQ "SQUARE"){
         return new Square();
         
      }else 
         return "not defined";
      }
}

Rectangle.cfc

component Rectangle extends="Shape" {
   function draw() {
      writeoutput("Inside Rectangle::draw() method. <br/>");
   }
}

AbstractFactory.cfc

abstract component AbstractFactory {
     abstract Shape function getShape(String shape) ;
}

FactoryProducer.cfc

component FactoryProducer {
 AbstractFactory function getFactory(String choice){
   if(choice eq "SHAPE"){
         return new ShapeFactory();
         
      }
      
   }
}

index.cfm

<cfscript>
   //get shape factory
   shapeFactory =  new FactoryProducer().getFactory("SHAPE");
   //get an object of Shape Rectangle
   shape2 = new shapeFactory().getShape("RECTANGLE");
   //call draw method of Shape Rectangle
   shape2.draw();
   //get an object of Shape Square 
   shape3 = new shapeFactory().getShape("SQUARE");
   //call draw method of Shape Square
   shape3.draw();
</cfscript>

final コンポーネント、final メソッド、final 変数

ColdFusion では、継承は非常に有用な機能です。しかし、データのセキュリティ違反を防ぐために、コンポーネントを他のクラスで拡張してはいけない場合があります。そうした場合のために、final キーワードがあります。

ColdFusion では次がサポートされています。

  • final コンポーネント
  • final メソッド
  • final 変数

final 変数

final 変数 は 定数です。変数を宣言する際に final キーワードを使用します。final 変数は初期化後に値を変更することができません。次に例を示します。

component{
 final max=100;
  
 function mymethod(){
  //max=100;
  writeoutput("final variable is: " & max);
 }
}

index.cfm を作成し、コンポーネントをインスタンス化して、そのコンポーネントに定義されているメソッドを呼び出します。そのメソッドで max の値を変更すると、例外が発生します。次のスニペットでも例外が生成されます。

component{
 final max;
 // constructor
 
 function mymethod(){
  max=50;
  writeoutput("final variable is: " & max);
 }
}

final コンポーネント

final コンポーネントを拡張し、final メソッドをオーバーライドすることはできません。ただし、final コンポーネントで他のコンポーネントを拡張することはできます。

final コンポーネントを宣言するには、以下の例を参照してください。

final component{
 // define methods
}

final メソッドを定義するには、final キーワードと戻り型の前に指定子を使用します。次に例を示します。

public final void function myMethod() {
 // method body
}

final コンポーネントはデータのセキュリティを確保するのに役立ちます。ハッカーはよくコンポーネントのサブコンポーネントを作成し、それを元のコンポーネントと置き換えます。そのサブコンポーネントは元のコンポーネントに似ていますが、悪意のある操作を実行し、アプリケーション全体が危険にさらされる可能性があります。そうした行為を防ぐには、コンポーネントを final として宣言し、サブコンポーネントを作成できないようにします。次に例を示します。

A.cfc

final component {
}

以下のコードでは例外が生成されます。

B.cfc

component extends=”A” {
}

final メソッド

final キーワードを使用したメソッドはオーバーライドできません。そのため、サブコンポーネントから変更できない機能を作成できます。次に例を示します。

Test.cfc

component {
 // final method and cannot be overridden
 public final void function display(){
  writeOutput("From super class, final display() method");
 }
 // concrete method
 public void function show(){
  writeOutput("From super class, non-final show() method");
 }
}

Demo.cfc

component extends="Test"{
 //public void function display(){}
 public void function show()
   {
     writeOutput("From subclass show() method");
   }
}

Demo. cfc では、上記の行のコメントを解除すると 例外が生成されます。 final メソッドはオーバーライドできないからです。ただし、上記のコードに示すように、final 以外のメソッドはオーバーライドできます。

main.cfm

<cfscript>
 d1=new Demo();
 d1.display();
 d1.show();
</cfscript>

出力

From super class , final display() method

From subclass show() method

インターフェイスのデフォルトの関数

この機能を使用すると、シグネチャではなく、インターフェイスの関数を宣言できます。開発者は、インターフェイスを拡張する際に、デフォルトの実装をオーバーライドするか、再利用するかを選択できます。

デフォルトの関数を使用すると、古いアプリケーションとの互換性を保ったままインターフェイスを拡張できます。

例えば、any 型のオブジェクトを返す returnsany 関数を定義する I.cfc インターフェイスを作成します。そうした関数を定義する際に、「default」キーワードを使用します。

interface {
 public default any function returnsany(any obj)
 {
  return obj;
 }
}

I.cfc インターフェイスを実装する comp.cfc を作成します。

component implements="I"
{

}

次に、文字列を返すオブジェクトを作成します。

<cfscript>
 myobj=new Comp();
 writeOutput(myobj.returnsany("hello world"));
</cfscript>

共変性

共変性とは、型とサブ型の間の関係です。ColdFusion(2021 リリース)では、メソッドをオーバーライドする際の戻り型で共変性がサポートされています。

ColdFusion(2021 リリース)では、インターフェイスを実装するコンポーネントの戻り型は共変です。以下の例は、共変性を利用する方法を示しています。

インターフェイスの実装時に引数名は比較されません。つまり、インターフェイスの関数が引数名を x として受け取っても、コンポーネントに実装されている関数では任意の引数名を使用できます。

  1. IAnimal.cfc インターフェイスを定義します。

    interface displayName="IAnimal" hint="Animal Interface."{
         
        any function eat(any prey="");
        any function makeNoise(string noise);
         
    }
  2. インターフェイスを実装するコンポーネント Animal.cfc を定義します。

    インターフェイス関数 eat() および makenoise () の実装時に、戻り値の型がより具体的な型にオーバーライドされます。これはメソッドの共変戻り値型と呼ばれます。

    component implements="IAnimal" displayname="Animal"{
     property animalSize;
     property animalType;
     function init(animalSize,animalType){
      variables.instance.animalSize = arguments.animalSize
      variables.instance.animalType = arguments.animalType
     }
     Animal function eat(any prey=""){
       return prey;
      }
     string function makeNoise(string noise){
       return noise;
      }
     function getanimalSize(){
      return variables.instance.animalSize
     }
     function getanimalType(){
      return variables.instance.animalType
     }
    }
  3. index.cfm を作成し、これらの関数の動作を確認します。

    <cfscript>
     bunny=new Animal('small','rabbit');
     simba =new Animal('large','Tiger');
     writeoutput("Simba eats " & simba.eat(bunny).getAnimaltype() & "<br/>");
     writeoutput("Simba " & simba.makenoise('roarsss'));
    </cfscript>
アドビのロゴ

アカウントにログイン