July 12, 2018
OOP and ColdFusion
Comments
(1)
July 12, 2018
OOP and ColdFusion
Staff 4 posts
Followers: 2 people
(1)

Object-Oriented Programming is common term in programming language. It’s a vast concept but to sum it up in a single line, it is a set of concepts and techniques that make use of the “object” construct, to write more reusable, maintainable, and organized code. Objects are implemented differently in every language. In ColdFusion, we have ColdFusion Components (CFCs) that can be instantiated to create objects.

Anyone who has ever studied OOP must know that there are four main concepts, which are:

  • Abstraction
  • Encapsulation
  • Inheritance
  • Polymorphism

Let’s us first have a look on how these concepts are implemented in ColdFusion.

Abstraction

The main goal of abstraction is to handle complexities by hiding unnecessary details from user. Like when we drive a car, we are unaware of how the engine works. Abstraction is implemented in most languages by defining a class that has methods, properties & constructors.

In ColdFusion, class is simply a CFC. A CFC has private & public properties as well as methods. Variables defined in ‘this’ scope of CFC are public, while those in ‘variable’ scope are accessible to CFC. You can also define variables that are private to methods by defining them in ‘local’ scope. CFCs can be instantiated by either using CreateObject() or the new operator.

Encapsulation

Encapsulation is the concept of keeping data & the methods operating on this data in a single unit, i.e. class. This concept also involves information hiding. The basic idea is to bundle accessor methods with data that are not visible from outside of a class. Accessor methods are the methods that give read/write access to private data, commonly known as getter/setter methods.

In ColdFusion, you can define accessors for CFC properties. ColdFusion can automatically generate accessors if you set the property ‘accessor’ as true for a CFC.

Inheritance

Inheritance is a way to reuse existing code, or a way to write code in one location that many objects can make use of. When an object of class B inherits from class A, object B contains all the code — that is, methods and data — from class A, plus all the code from object B.

In ColdFusion, CFCs can extend to inherit functions & properties. ColdFusion does not allow multiple inheritance but a CFC can implement multiple interfaces. Interfaces can be extended too.

Polymorphism

Polymorphism describes the concept that objects of different types can be accessed through the same interface. In most languages, polymorphism is implemented by ‘Method Overloading‘ & ‘Method Overriding‘.

In ColdFusion, we support ‘Method Overriding’. This means that a child CFC can override parent CFC’s method to to customize or completely replace the behavior of that method.

Now that we covered the basics, let’s see how Abstract Classes & Methods can be used in ColdFusion.

Abstract Classes & Methods

An abstract class allows you to make a ‘template’ for classes that will eventually inherit from it, without writing unnecessary code for a parent class that is never instantiated. Therefore, abstract class cannot be instantiated but can be extended.

Abstract classes can have both abstract and concrete methods. Abstract methods have no body. Declaring abstract methods in a class allows you to specify certain methods that must be implemented by the inheriting classes. In an inheritance hierarchy the first non-abstract class should implement all the abstract methods.

Abstract Component & Methods have been introduced in the newest version of ColdFusion, ColdFusion 2018. They can be defined using the keyword ‘abstract’. A non-abstract CFC cannot have abstract methods whereas an abstract CFC can have both abstract and concrete methods.

Let’s create a CFC wild kingdom to understand this concept.

At the highest level is an Animal CFC. This is an abstract CFC that encapsulates methods and data that are common to any kind of animal. This includes the animal’s size and type. This CFC cannot be instantiated. It can be extended and has concrete and abstract methods. Abstract methods defined are, eat() and makeNoise().  These must be overridden by subclass of Animal.

 

abstract component displayName="Animal" hint="Abstract Animal CFC."{
	
	property animalSize;
	property animalType;
	
	function init(animalSize,animalType){
		
		variables.instance.animalSize = arguments.animalSize
		variables.instance.animalType = arguments.animalType 
	}
	abstract function eat(any prey="")
	abstract function makeNoise()
	
	function getanimalSize(){
		return variables.instance.animalSize
	}
	
	function getanimalType(){
		return variables.instance.animalType
	}
}

Mammal CFC is a subclass of Animal. Just like Animal, the purpose of the Mammal CFC is to wrap up data and methods common to all Mammals. In this example, Mammal doesn’t do much, but you can imagine it handling methods like growHair(). Mammal is also an abstract CFC, like Animal.

abstract component extends="Animal" displayName="Mammal" hint="Abstract Mammal CFC."{
	
	function init(mammalSize,mammalType){
		super.init( arguments.mammalType, arguments.mammalSize )
		return this
	}
}

I’ve created CFCs that extend Mammal: a Mouse and a Feline. Mouse is a concrete CFCs, which means you can create instances of these CFCs.

component extends="mammal" displayName="Mouse" hint="Concrete CFC Mouse."{
         
         function init(){
             super.init( 'Mouse', 'small' ) 
             return this
         }
         function eat(any cheese){
            return "I like #cheese#."
         }
         function makeNoise(){
            return "Squeak." 
         }
}

Feline is another abstract class which could encapsulate methods that apply to all felines, like purr().

abstract component extends="Mammal" displayName="Feline" hint="Abstract Feline CFC."{
        
        function init(felineSize,felineType){
                super.init( arguments.felineType, arguments.felineSize )
                variables.instance.isPurring = false
                return this
         }
 }

And finally, the concrete subtypes of Feline are Tiger and Housecat.Tiger and Housecat have their own way of handling method calls like eat() and makeNoise().

component extends="feline" displayName="Tiger" hint="Concrete CFC Tiger."{
            
             function init(){
                    super.init( 'Tiger', 'large' )
                    return this 
             }
             function eat(Animal prey){
                  if( arguments.prey.getAnimalSize() eq 'large')
                        return "Crunch...gulp. Mmmmmm." 
                  else
                        return "Are you crazy? I can't eat that!" 
             }
 
             function makeNoise(){
                   return "ROAR!!!!" 
             }
}

component extends="Feline" displayName="HouseCat" hint="Concrete CFC Housecat."{
           
            function init(){
                   super.init( 'Housecat', 'small' )
                   return this
             }
           function eat(Animal prey){
                  if( arguments.prey.getAnimalSize() eq 'small')
                       return "Crunch...gulp. Mmmmmm." 
                  else
                       return "Are you crazy? I can't eat that!" 
           }
           function makeNoise(){
               return "Meow." 
          }
}

Let’s check what my animals eat what & what noise do they make.

<cfscript>
	 minimouse=new Mouse();
	 writeoutput("MiniMouse :" minimouse.makenoise() & "<br/>");
	 writeoutput(minimouse.eat("cheese") & "<br/>");
	 mykitty=new HouseCat();
	 writeoutput(mykitty.eat(minimouse));
</cfscript>

Output:

 

 

I hope you guys are clear on how to create Abstract Classes & Methods in ColdFusion. I will write another blog which would describe other newly introduced OOP features.

1 Comment
2021-08-17 16:52:58
2021-08-17 16:52:58

The “Output” section at the bottom of this example shows no output.

Like
(1)
Add Comment