# OOP - Polymorphism

Polymorphism is one of 3 foundational concepts of Object Oriented Programming. Polymorphism can be translated to mean *many forms*. In OOP, polymorphism means that one object can be considered to have many forms. An object-reference of the base-class type can refer to either a base-class object or a child-class object. Another way to consider this is that when we have a collection of similar objects, where we refer to them with the more generalized format (base-class type object-reference variable), that variable can refer to any of the child-class objects.

In the example below, this is intuitive for us: a dog is an animal, a cat is an animal, an animal is an animal. However, a dog is not a cat, and we can'd force some instance of an animal to be strictly a cat, we would expect this to cause errors as in the example code below.

```java
Animal[ ] animals = new Animal[3];
animal[0] = new Dog();
animal[1] = new Cat();
animal[2] = new Animal( );

Cat cat = new Cat( );
cat = new Dog( ); ///this will cause an error
cat = new Animal( );  ///this will cause an error
```

So, polymorphism means that child-class objects can be to be treated as their more general, base-class type, and this reflects our intuition about relationships between real-world objects. My pet, Charlie, is an instance of a dog object, but he can also be considered as an animal, which would be the more general concept, or base-class concept.

## Object References

We can create an object reference variable of the base-class type, and this variable can be used to reference either a base-class object, or any object that is of a child-class type. We can imagine a set of classes, where Animal is the base-class, where Cat and Dog would be child-classes that extend Animal. Below are examples using default constructors to demonstrate using base-class object references to refer to child-class object instances. It is important to note that the reverse is not true, you can not use an object-reference of the Child-class type to refer to a base class object.

## Array of base-class object references

```java
Animal[] animals= new Animal[3] //array of base-class object references
animals[0] = new Animal( ); //base-class object

Dog dog1 = new Dog( );  //child-class object
animals[1] = new Dog( );  //base-class type object reference, child-class object

Cat cat1 = new Cat( );
animals[2] = new Cat( );

//IMPORTANT:  Note that these will cause errors:
cat1 = animals[0];  //child-class reference-type, base-class object

cat1 = dog1; //child class reference-type
```

## Over-riding Methods

OOP Polymorphism means that when a child-class object executes a method, then the 'system' will determine whether to execute a child-class method or a base-class method, by examining the child class definition to see if the method has been implemented in the child-class so that it over-rides the base-class method. Method over-riding allows us to treat objects using the more general, base-class, references, but that the 'system' will determine the run-time type of each object instance, and determine whether a base-class or child-class method will be executed. If a method has not been over-ridden in a child class, the child-class object can still call any method specified in the base-class, the child-class 'gets' everything in the base-class 'for free' when it extends the base-class to become a child-class.

## Object Oriented Design

Polymorphism should be considered when designing classes with inheritance relationships. Only methods defined in the base-class can be called on using base-class object references, even if the object refers to a child-class object. Therefore, UML class diagrams provide a graphical representation to aid design and use of OOP classes and objects.

## UML Diagram of Inheritance Relationships

![](https://2308964916-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M0-KLgIQowgQ2sRmRGm%2F-M04eXfov2q8lvkrzSfw%2F-M04emXSX_0ma_5AiFpj%2FScreen%20Shot%202017-11-30%20at%202.09.48%20PM.png?generation=1581716828795753\&alt=media)

The diagram above shows a base-class: Creature, and 3 Child classes: Zombie, Cat, Fish

When creating object reference variables, we specify the data-type of the variable, and this impacts the methods that can be called for the object.

Example 1: **Base-class object-reference variable:**

```
Creature creature = new Fish( 10, 10, f ); 
```

This object can call any methods that are specified in the base-class.

```
creature.display();
creature.move( );
creature.attack( creature );  
```

This object can not call any methods that are not specified in the base-class, even if they are specified in the child-class for the object's actual data-type:

```
//this will cause an error:
creature.glubGlub( );
```

Example 2: **Child-class object-reference variable:**

```
 Fish fish = new Fish( 10, 10, f);
```

This object can call any methods specified in either it's base-class, or it's own class (Fish)

```
 fish.attack( fish );  //no error doing this
 fish.glubGlub( );
```

## Object Oriented Design - Add methods to the base-class to provide access to specialized behavior in child-classes.

When designing classes, as in the example above, we should identify any specialized behavior that will be exhibited by any child-class and create a method in the base-class that represents the generalized behaivor.

Example: We have a child-class: Fish, where the fish has a specialized behavior: glubGlub( ). Let's assume that can be considered as a more generalized concept: makeNoise( ), where other child classes might also share this behavior. If we define the method: makeNoise( ) in the base-class, then, within the Fish class, we can over-ride makeNoise( ), and call the glubGlub( ) method within makeNoise( ). Then any base-class object can call makeNoise( ), if the object happens to be a Fish, child-class object, it will have it's glubGlub( ) behavior executed.

```java
//within the Creature class: provide makeNoise( ) 

 void makeNoise( ){
     println("some creatures will make special noises by overriding this method");
 }
```

```java
//Within the Fish class: over-ride makeNoise( )
void makeNoise( ){
     this.glubGlub( );
 }
```

The image below shows an improved object-oriented design, so that all methods implemented in the base-class can be called by an object with a base-class type reference variable, and if the object is a child-class object, it'll have specialized behavior because it has provided an over-ride for methods where it has special logic to be executed

![](https://2308964916-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M0-KLgIQowgQ2sRmRGm%2F-M04eXfov2q8lvkrzSfw%2F-M04emXUgsJGkGuDrRme%2FScreen%20Shot%202017-12-04%20at%2010.38.18%20AM.png?generation=1581716829244748\&alt=media)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://kdoore.gitbook.io/cs1335-java-and-processing/object-oriented-programming/oop-polymorphism.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
