> ## Content Index
> Fetch the complete content index at: https://www.bulkifiedthinking.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Stop Writing Rigid Apex Code
- URL: https://www.bulkifiedthinking.com/stop-writing-rigid-apex-code/
- Published: 2026-07-25T18:19:03.000Z
- Updated: 2026-08-16T23:03:44.000Z
- Description: Polymorphism is the provision of a single definition to engineers who can explain “many forms”, yet still fill their Apex code with rigid if-else conditions. Don't be that engineer.
- Author: Andrii Sukhetskyi
- Tags: Apex, Developers

"In object-oriented programming, **polymorphism** is the provision of a single interface to entities of different types" – [Wikipedia](https://en.wikipedia.org/wiki/Main%5FPage?ref=bulkifiedthinking.com)

In my experience, polymorphism is the provision of a single definition to engineers who have no idea what that definition means. And I'm not saying that learning a term is a bad habit, but rather that the meaning behind it is more important than the definition itself.

Continuing this debate, when asked to provide examples of polymorphism, the answers often boil down to "Method Overriding" and "Method Overloading". But we're still not addressing what polymorphism actually is. I could use method overriding my entire life without realizing whether it's inheritance, polymorphism, both, or neither.

---

## Method Overloading

Method overloading in Apex allows the creation of multiple methods with the same name but different parameters. This is particularly useful when you have similar logic that applies to different parameter types. Instead of creating separate methods with distinct names, you can combine them under a single method name.

For example, consider the Apex [String](https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex%5Fmethods%5Fsystem%5Fstring.htm?ref=bulkifiedthinking.com) class, which includes an overloading of the `valueOf()` method. Depending on the type of the variable passed, different operations are performed, all while using the same method name.

![](https://storage.ghost.io/c/92/d5/92d55211-2cfe-45c9-b8c4-b7c7b1595cdb/content/images/2026/07/image-7.png)

In this case, the overloaded methods are defined **at compile time**. The methods are explicitly declared, allowing you to easily predict the outcome during code execution. This form of polymorphism is known as "Static Polymorphism". While it’s true that here polymorphism refers to these "different forms", the true beauty of polymorphism reveals when the behavior of the code becomes less predictable.

## Method Overriding

Method Overriding represents a more interesting structure, but we often demonstrate it incorrectly, why so? This example involves inheritance, another fundamental concept of Object-Oriented Programming (OOP) and that's why method overriding is often mistakenly presented as an example of inheritance rather than a true example of "Dynamic Polymorphism".

To begin, let's create a class called `Parent`. It will include a constructor to specify the age and a method that we will attempt to override in the child class.

![](https://storage.ghost.io/c/92/d5/92d55211-2cfe-45c9-b8c4-b7c7b1595cdb/content/images/2026/07/image-8.png)

As you may have noticed, we used the `virtual` keyword for both the class and the method. Why is this necessary? In Apex (unlike Java), all classes and methods are final by default. Therefore, if you want to extend a class, such as inherit from it or override a method — you must use the `virtual` keyword to explicitly indicate that the class or method is intended for extension.

In the next step, we will create a `Child` class that extends the `Parent` class and overrides the `giveAdvice()` method that you saw earlier in the parent class.

![](https://storage.ghost.io/c/92/d5/92d55211-2cfe-45c9-b8c4-b7c7b1595cdb/content/images/2026/07/image-9.png)

Finally, we come to the point of method overriding, where we have two classes, each with the same method but different logic inside. Sounds like polymorphism, correct? Well, not really. 

Do you remember I mentioned earlier that this example is often presented incorrectly? This is that moment. After implementing the second class and overriding the method, many show the code and say, "Look, this what Dynamic Polymorphism is'.

No, it’s not. You’ve explicitly defined two classes and their logic and how the hell is it supposed to be something not very predictable? True **dynamic polymorphism** is only demonstrated when you show how it’s used in practice. Specifically:

![](https://storage.ghost.io/c/92/d5/92d55211-2cfe-45c9-b8c4-b7c7b1595cdb/content/images/2026/07/image-10.png)

In the first method, we introduce exactly this "Dynamic Polymorphism". This is because, even though we specify an instance of the "Parent" class as a parameter, Apex allows us to pass any extended class as well, like this:

In the first version of the method, we introduce this "Dynamic Polymorphism". Even though the `extractAdvice()` method accepts an instance of the `Parent` class, Apex also allows us to pass an instance of any class that extends `Parent`, like this:

```apex
Parent newChild = new Child(5);
extractAdvice(newChild);
```

We create a `Child` instance using `new Child(5)`, but store it in a variable declared as `Parent`. This is possible because every `Child` is also a `Parent`.

When `extractAdvice()` calls `giveAdvice()`, Apex determines the actual type of the object at runtime. Since the object is a `Child`, Apex executes the overridden `Child.giveAdvice()` method, which returns `"Have Fun"`. This behavior is called "Dynamic Polymorphism" (or runtime polymorphism).

In the second version of `extractAdvice()`, we use `if-else` conditions to determine which code should be executed. This is not polymorphism. You can create the correct class hierarchy but still use it incorrectly by manually checking object types instead of allowing Apex to select the appropriate implementation at runtime.

## Dynamic Instantiation

While discussing the topic of Dynamic Polymorphism, I would also like to touch on instantiating a class at runtime. Some argue that this is not strictly part of polymorphism, though I disagree.

Consider the case where we have a class name represented as a string, like this:

```apex
String className = 'MyClass';
```

How would you create an instance of this class in this scenario? Salesforce provides us with a great class called [Type](https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex%5Fmethods%5Fsystem%5Ftype.htm?ref=bulkifiedthinking.com) that allows us to do this easily and seamlessly. Let's put it into practice:

![](https://storage.ghost.io/c/92/d5/92d55211-2cfe-45c9-b8c4-b7c7b1595cdb/content/images/2026/07/image-11.png)

In this example, we pass our class name to the method as a string, and using the [Type](https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex%5Fmethods%5Fsystem%5Ftype.htm?ref=bulkifiedthinking.com) class, we can instantiate it with a combination of the `getName()` and `newInstance()` methods.

But wait... If we instantiate this class dynamically, how did I manage to specify the name `GoogleAuthorizer` statically? How did I know?

It’s all thanks to the fact that `GoogleAuthorizer` is not a class, but an interface.

This means that when using this method, we must ensure that any class passed as a string strictly adheres to this particular interface. This allows us to predict exactly what methods it contains. 

In this case, I am confident that the passed class will include the method `retrieveAccessToken()` because it is part of the interface, and as we know, everything defined in an interface must be implemented by the class that implements it.

## What Exactly is Polymorphism?

As you may have noticed, it comes in two types: Static Polymorphism and Dynamic Polymorphism. Furthermore, the term "Polymorphism" is not limited to "different forms"; it represents a structure in which our code becomes less predictable and more generalized, making it easier to reuse and more flexible to extend.