三角形、長方形、円があります。
1.それぞれの面積を求める関数を作りなさい
2.それぞれの周辺の長さを求める関数を作りなさい
3.それぞれの面積を合計した関数を作りなさい
4.それぞれの周辺の長さを合計した関数を作りなさい
今回はオブジェクト指向で考えて作って見ます。
オブジェクトとしては、
三角形、長方形、円、ですね。
動きとしては、
面積の計算、
長さの計算
が、共通しています。
よく使う関数の場合は、引数が必要になりますが、
オブジェクト指向の場合は、
事前にデータを渡しておき、
そのデータをもとに計算することができます。
そうすると、三角形、長方形、円は
引数なしの関数で、
calcMenseki
calcNagasa
と、することができます。
オブジェクト指向の特徴としては、
ポリモーフィズム(多態性)というものがあります。
「多態性(Polymorphism)」とは、オブジェクト指向における
「実行される処理の実体が、コールされたメッセージではなく、
メッセージを受けたオブジェクトによって決定される性質」のことです。
http://codezine.jp/article/detail/3709
例えば、三角形というオブジェクトに対して
calcMenseki
というメッセージを受けると
その三角形の面積の計算を行う、
ということです。
それでは以下はオブジェクト指向を使った例です。
●基本オブジェクト
●obj.cfc
<cfcomponent>
<!---=========================================
init
==========================================--->
<cffunction name="init" returnType="obj" output="no">
<cfreturn this>
</cffunction>
</cfcomponent>
●三角形オブジェクト
●sankaku.cfc
<cfcomponent extends="obj">
<cfset variables.teihen = 0>
<cfset variables.takasa = 0>
<cfset variables.hen1 = 0>
<cfset variables.hen2 = 0>
<cfset variables.hen3 = 0>
<cffunction name="calcMenseki" returnType="numeric" output="no">
<cfreturn (variables.teihen * variables.takasa / 2) >
</cffunction>
<cffunction name="calcNagasa" returnType="numeric" output="no">
<cfreturn (variables.hen1 + variables.hen2 + variables.hen3) >
</cffunction>
<!--- setter --->
<cffunction name="setTeihen" returnType="void" output="no">
<cfargument name="teihen" type="numeric" required ="yes">
<cfset variables.teihen = arguments.teihen>
</cffunction>
<cffunction name="setTakasa" returnType="void" output="no">
<cfargument name="takasa" type="numeric" required ="yes">
<cfset variables.takasa = arguments.takasa>
</cffunction>
<cffunction name="setHen1" returnType="void" output="no">
<cfargument name="hen1" type="numeric" required ="yes">
<cfset variables.hen1 = arguments.hen1>
</cffunction>
<cffunction name="setHen2" returnType="void" output="no">
<cfargument name="hen2" type="numeric" required ="yes">
<cfset variables.hen2 = arguments.hen2>
</cffunction>
<cffunction name="setHen3" returnType="void" output="no">
<cfargument name="hen3" type="numeric" required ="yes">
<cfset variables.hen3 = arguments.hen3>
</cffunction>
</cfcomponent>
●長方形オブジェクト
●shikaku.cfc
<cfcomponent extends="obj">
<cfset variables.tate = 0>
<cfset variables.yoko = 0>
<cffunction name="calcMenseki" returnType="numeric" output="no">
<cfreturn (variables.tate * variables.yoko) >
</cffunction>
<cffunction name="calcNagasa" returnType="numeric" output="no">
<cfreturn ((variables.tate * 2) + (variables.yoko * 2)) >
</cffunction>
<!--- setter --->
<cffunction name="setTate" returnType="void" output="no">
<cfargument name="tate" type="numeric" required ="yes">
<cfset variables.tate = arguments.tate>
</cffunction>
<cffunction name="setYoko" returnType="void" output="no">
<cfargument name="yoko" type="numeric" required ="yes">
<cfset variables.yoko = arguments.yoko>
</cffunction>
</cfcomponent>
●円オブジェクト
●en.cfc
<cfcomponent extends="obj">
<cfset variables.hankei = 0>
<cffunction name="calcMenseki" returnType="numeric" output="no">
<cfreturn (variables.hankei * variables.hankei * 3.14) >
</cffunction>
<cffunction name="calcNagasa" returnType="numeric" output="no">
<cfreturn (2 * variables.hankei * 3.14) >
</cffunction>
<!--- setter --->
<cffunction name="setHankei" returnType="void" output="no">
<cfargument name="hankei" type="numeric" required ="yes">
<cfset variables.hankei = arguments.hankei>
</cffunction>
</cfcomponent>
●オブジェクトをいれる箱オブジェクト
●objbox.cfc
<cfcomponent>
<cfset variables.aryObj = arrayNew(1)>
<cffunction name="init" returnType="objbox" output="no">
<cfreturn this>
</cffunction>
<cffunction name="setObj" returnType="void" output="no">
<cfargument name="obj" type="obj" required ="yes">
<cfset ArrayAppend(variables.aryObj, arguments.obj)>
</cffunction>
<cffunction name="calcMenseki" returnType="numeric" output="no">
<cfset var local = structNew()>
<cfset local.gokei = 0>
<cfloop index="local.idx" array="#variables.aryObj#">
<cfset local.gokei = local.gokei + local.idx.calcMenseki()>
</cfloop>
<cfreturn local.gokei>
</cffunction>
<cffunction name="calcNagasa" returnType="numeric" output="no">
<cfset var local = structNew()>
<cfset local.gokei = 0>
<cfloop index="local.idx" array="#variables.aryObj#">
<cfset local.gokei = local.gokei + local.idx.calcNagasa()>
</cfloop>
<cfreturn local.gokei>
</cffunction>
</cfcomponent>
●実際の処理
●index.cfm
<cfparam name="url.p" default="">
<!--- objbox作成 --->
<cfset objbox = CreateObject("component", "objbox").init()>
<!--- 三角形を2つobjboxにセット --->
<cfloop index="idx" from="1" to="2">
<cfset objSan = CreateObject("component", "sankaku").init()>
<cfset objSan.setTeihen(3)>
<cfset objSan.setTakasa(4)>
<cfset objSan.setHen1(3)>
<cfset objSan.setHen2(4)>
<cfset objSan.setHen3(5)>
<cfset objbox.setObj(objSan)>
</cfloop>
<!--- 長方形を3つobjboxにセット --->
<cfloop index="idx" from="1" to="3">
<cfset objShi = CreateObject("component", "shikaku").init()>
<cfset objShi.setTate(5)>
<cfset objShi.setYoko(6)>
<cfset objbox.setObj(objShi)>
</cfloop>
<!--- 円を4つobjboxにセット --->
<cfloop index="idx" from="1" to="4">
<cfset objEn = CreateObject("component", "en").init()>
<cfset objEn.setHankei(7)>
<cfset objbox.setObj(objEn)>
</cfloop>
<cfoutput>
<cfif url.p eq "menseki">
menseki gokei = #objbox.calcMenseki()#
</cfif>
<cfif url.p eq "nagasa">
nagasa gokei = #objbox.calcNagasa()#
</cfif>
</cfoutput>
index.cfmの動きとしては、
1.三角形などのオブジェクトを作って、箱オブジェクトにいれる。
2.指定した処理で、箱オブジェクトの処理
面積の合計など行っています。
箱オブジェクトが「多態性」をうまく利用しています。
また「継承」も利用しています。
関数をあらためて見てみます。
●setObj関数
<cffunction name="setObj" returnType="void" output="no">
<cfargument name="obj" type="obj" required ="yes">
<cfset ArrayAppend(variables.aryObj, arguments.obj)>
</cffunction>
あらかじめ用意したvariables.aryObj配列変数に
オブジェクトをセットしています。
引数のtypeがobjとなっていますが、
これはobj.cfcを意味しています。
obj.cfcを継承している三角形、長方形、円オブジェクトを
セットすることができます。
●calcMenseki関数
<cffunction name="calcMenseki" returnType="numeric" output="no">
<cfset var local = structNew()>
<cfset local.gokei = 0>
<cfloop index="local.idx" array="#variables.aryObj#">
<cfset local.gokei = local.gokei + local.idx.calcMenseki()>
</cfloop>
<cfreturn local.gokei>
</cffunction>
local.gokei変数にセットしている行がキモですね。
local.idx.calcMenseki()
この部分は、それぞれのオブジェクトに対する関数を使っています。
三角形なら三角形用のcalcMenseki関数、
長方形なら長方形用のcalcMenseki関数、
円なら円用のcalcMenseki関数、
を、使っています。
考え方によっては、シンプルに作ることができますね。