三角形、長方形、円があります。
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関数、
を、使っています。
考え方によっては、シンプルに作ることができますね。