Object-Oriented Programming – Parents and Children

This post is going to be a somewhat short abstract about the concept of parents and children in object-oriented programming (OOP). The first thing of which people new to OOP need to be aware is that parents and children are are not handled as logical parents and children, they are handled more like biological parents and children. It is best to think of the parent/child relationship in OOP as a concept of “inheritance” rather than a concept of containers and contained elements.

When manipulating the DOM, a parent is one object, and a child is another object contained within. However, in OOP, you have to think more of the classes than the individual objects themselves. In OOP, a parent is one class, and a child is another class that inherits all of the attributes and functions assigned to the parent class.

In other words, in DOM, you would do something like the following:

<div class="parent">
  <div class="child">
    This is my text
  </div>
</div>

The div with the class of “parent” is the parent element. The div with the class of “child” is actually a parent and a child; as it is the child of the “parent” div, and a parent of the text contained within. In the DOM, parents are simply containers for the children within.

In OOP, however, parents and children are a completely different animal. Setting up parents and children in PHP 5 could look something like:

class parentobj {
	public $attr1;
	public $attr2;

	function echoparams() {
		foreach($this as $key=>$val) {
			echo (string) "The parameter named $key is equal to $val<br />";
		}
	}
}
class childobj extends parentobj {
	public $attr3;
	public $attr4;

	function makeupper() {
		$this->attr4 = strtoupper($this->attr3);
	}
}

$myobj = new childobj;
$myobj->attr1 = 'This is my first attribute';
$myobj->attr2 = 'This is my second attribute';
$myobj->attr3 = 'This is my third attribute';
$myobj->makeupper();
$myobj->echoparams();

The function $myobj->echoparams will actually echo all four attributes, because the “childobj” inherits the “echoparams” function and the parameters “attr1” and “attr2” from the “parentobj”.

The output of the script above would look like:

The parameter named attr3 is equal to This is my third attribute
The parameter named attr4 is equal to THIS IS MY THIRD ATTRIBUTE
The parameter named attr1 is equal to This is my first attribute
The parameter named attr2 is equal to This is my second attribute

Here are some other ways to think of the parent/child relationships in OOP programming:

  • In OOP, a book would likely be a child of printed items, rather than being a child of some sort of container like a library.
  • If you create a class called “car”, its parent class would be something like “vehicles”, whereas in DOM and other logical uses of the parent/child relationship, “car” would be the child of something like “fleet”.
  • If you create a class for “database”, “table” would not be a child class, it would have to be a completely separate class.
  • You could also think of “cats” and “people” as child classes of a “mammal” class. Further, you could think of that “mammal” class as a child of the “animal” class.

Real-Life Example

For me, this took a lot of getting used to. The problem was compounded by the fact that my first real foray into OOP was developing a form generator/processor script.

In my mind, fieldsets were logically children of forms, and form fields were logically children of fieldsets. In HTML and the DOM, that’s exactly the way the parent/child relationship is defined. In OOP, however, that’s not the way it works at all.

Instead, I had to start thinking of the parent/child relationship in a whole new way. Once I finally got my head around it, I realized that the parent/child did have a place in the script I was developing. Rather than thinking of the form as the parent and the fieldsets and form fields as children, I had to begin thinking of it this way:

The generic form field is the parent

The “input”, “select” and “textarea” elements were the children of the “form field” class (in my particular script, the checkbox group and the radio button group were also separate children of the form field class). Because I needed all of the same basic information, such as the element name, the default value, the label, etc., no matter which form field I was generating, I set all of those as parameters in my formfield class. However, since a textarea is built differently than a select element, which is built differently than a standard text input, I needed separate classes for each of those.

Therefore, even though I still set up my logical parents and children (the form class, the fieldset class and the formfield class), I also set up my OOP parents and children (I have a “formset” as a child of my fieldset class, which helps group the entire set of form fields and fieldsets together, in case I need to generate the same group of inputs more than once on a page; and I have my input, select, textarea, checkgroup and radiogroup as the children of my formfield class).

I use the logical definition of the parent/child relationship by storing arrays of my formfields inside of a single parameter in my fieldset class, and I store arrays of my fieldsets in a single parameter of my form class. That way, I can easily loop through all of the logical children of each element.

However, as I mentioned, I also use the OOP (or, as I like to think of it, the biological) definition of the parent/child relationship, using a single class to easily hold all of my common functions and parameters that are used in all of the child classes.

Conclusion

I hope my article will help a few people understand the way parent/child relationships are defined in OOP. You have to be careful how you think of these relationships. If you are new to object-oriented programming, you will most likely have to completely re-learn the way you think of parents and children.