Oh.. this is a feature supported by programming languages to varying degrees. For static-typing
programming languages like C
, Ada
, Haskell
, Java
, and C#
, the expression of Polymorphism
logic in the code will depend a lot on the tools that each language provides; As for dynamic-typing
languages like JavaScript
, Python
, or Ruby
, there’s basically no limit to expression.
We’ll start with the definition put together by Wikipedia
Polymorphism
in programming is generally the use of1 tên định danh
to represent or representnhiều kiểu dữ liệu khác nhau
. The concept is borrowed from the field of biological research, where one identifier is used to describe a group of different species.
_Wikipedia
And also according to this log, the ways to represent polymorphism in the programming environment can be divided into 3 groups:
Sub-typing
– when an identifier is used to denote anyobject
in many differentclass
that share the samesuper class
.Ad-hoc
– when the given code defines a common programming interface for a random set of value types.Parametric
– When the code does not specify a concrete data type and instead abstract symbols are used as a substitute for the ability to accept any data type.
Sub-typing Polymorphism
This is the most basic aspect of Polymorphism
logic, and it is easy to spot the similarity with the definition given in the quotation box above. Here we will make a simple example with the class
present in the diagram as follows:
We have class Shape
that have a show()
method that is inherited by other class
Circle
, Square
, and Triangle
. And in inherited class
, the show()
method is redefined to have the appropriate performance results for each class
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
<span class="token keyword">class</span> <span class="token class-name">Main</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">main</span> <span class="token punctuation">(</span> <span class="token class-name">String</span> args <span class="token punctuation">[</span> <span class="token punctuation">]</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token class-name">Shape</span> form <span class="token operator">=</span> <span class="token keyword">null</span> <span class="token punctuation">;</span> form <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Circle</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> form <span class="token punctuation">.</span> show <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> form <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Square</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> form <span class="token punctuation">.</span> show <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> form <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Triangle</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> form <span class="token punctuation">.</span> show <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">//. Main</span> <span class="token keyword">class</span> <span class="token class-name">Shape</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">void</span> show <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token class-name">System</span> <span class="token punctuation">.</span> out <span class="token punctuation">.</span> println <span class="token punctuation">(</span> <span class="token string">"-- Shape - - - - - - - - - - -"</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">//. Shape</span> <span class="token keyword">class</span> <span class="token class-name">Circle</span> <span class="token keyword">extends</span> <span class="token class-name">Shape</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">void</span> show <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span> <span class="token punctuation">.</span> show <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token class-name">System</span> <span class="token punctuation">.</span> out <span class="token punctuation">.</span> println <span class="token punctuation">(</span> <span class="token string">"Type of Shape : Circle n"</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">//. Circle</span> <span class="token keyword">class</span> <span class="token class-name">Square</span> <span class="token keyword">extends</span> <span class="token class-name">Shape</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">void</span> show <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span> <span class="token punctuation">.</span> show <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token class-name">System</span> <span class="token punctuation">.</span> out <span class="token punctuation">.</span> println <span class="token punctuation">(</span> <span class="token string">"Type of Shape : Square n"</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">//. Square</span> <span class="token keyword">class</span> <span class="token class-name">Triangle</span> <span class="token keyword">extends</span> <span class="token class-name">Shape</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">void</span> show <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span> <span class="token punctuation">.</span> show <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token class-name">System</span> <span class="token punctuation">.</span> out <span class="token punctuation">.</span> println <span class="token punctuation">(</span> <span class="token string">"Type of Shape : Triangle n"</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">//. Triangle</span> |
Now in the main
program, we just declare a single form
variable that is typed to store an object
compatible with the class Shape
. Here we can understand that this variable will only allow storing an object
created directly from the class Shape
by implementing new Shape()
, or created from other class
that inherit the class Shape
.
This is điều kiện cần
in the definition of Polymorphism
, which is when a form
identifier can represent object
of many different class
. However, the remaining factor, or điều kiện đủ
to complete the definition of Sub-typing Polymorphism
, is the compatibility of the API
programming interface to open the code for external use of the class
.
To make it short, when we call show()
method in any case, from object
created from any class
where the code can still work, then we can identify the usage The form
identifier as above is a way of expressing Sub-typing Polymorphism
.
1 2 3 4 5 6 7 8 9 |
-- Shape - - - - - - - - - - - Type of Shape : Circle -- Shape - - - - - - - - - - - Type of Shape : Square -- Shape - - - - - - - - - - - Type of Shape : Triangle |
By the way, in programming languages that support OOP
syntax like Java
, C#
, Ruby
, Python
, JS
, etc., the operation when we redefine a property
or method
element in the inherited class
when that element has been defined in the super class
– called override
.
override
is always associated with the definition of Sub-typing Polymorphism
, but we need to keep in mind – that Sub-typing Polymorphism
also requires compatibility with the programming interfaces provided by class
. So if we override
the elements and change the access modifier
labels to hide from the usable surface from outside code, it’s not Sub-typing Polymorphism
anymore.
Expressing the logic of Sub-typing Polymorphism
as above in JavaScript
, of course , has no problems and is much more convenient because JS
is a dynamic-typing
language . Elements like using the name of the super class
to type the wildcard only make sense in the environment of static-typing
languages like Java
, C#
, etc..
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
<span class="token keyword">class</span> <span class="token class-name">Shape</span> <span class="token punctuation">{</span> <span class="token function">show</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> <span class="token string">"-- Shape - - - - - - - - - - -"</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">//. Shape</span> <span class="token keyword">class</span> <span class="token class-name">Circle</span> <span class="token keyword">extends</span> <span class="token class-name">Shape</span> <span class="token punctuation">{</span> <span class="token function">show</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span> <span class="token punctuation">.</span> <span class="token function">show</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> <span class="token string">"Type of Shape : Circle n"</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">//. Circle</span> <span class="token keyword">class</span> <span class="token class-name">Square</span> <span class="token keyword">extends</span> <span class="token class-name">Shape</span> <span class="token punctuation">{</span> <span class="token function">show</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span> <span class="token punctuation">.</span> <span class="token function">show</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> <span class="token string">"Type of Shape : Square n"</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">//. Square</span> <span class="token keyword">class</span> <span class="token class-name">Triangle</span> <span class="token keyword">extends</span> <span class="token class-name">Shape</span> <span class="token punctuation">{</span> <span class="token function">show</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span> <span class="token punctuation">.</span> <span class="token function">show</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> <span class="token string">"Type of Shape : Triangle n"</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">//. Triangle</span> <span class="token comment">// - main - - - - - - - - - </span> <span class="token keyword">var</span> form <span class="token operator">=</span> <span class="token keyword">null</span> <span class="token punctuation">;</span> form <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Circle</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> form <span class="token punctuation">.</span> <span class="token function">show</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> form <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Square</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> form <span class="token punctuation">.</span> <span class="token function">show</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> form <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Triangle</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> form <span class="token punctuation">.</span> <span class="token function">show</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
Ad-hoc Polymorphism
Ad-hoc Polymorphism
– when the given code defines a common programming interface for a random set of value types.
This definition actually comes from the Procedural
and Functional
topic languages, where each identifier name of the sub-program
can be seen as a definite morphological point.
The idea here is that a sub-program
called sum
can be understood as a name that stands for different modes of activity or mindset
. We can use sum(a,b)
to get the sum of two input values, or we can use sum(array)
to get the sum of all values in the array array
, etc..
As such, the identifier sum
has been used to represent many different sets of mindset
logic and can be used with different input
data elements; And that can be seen as a manifestation of Polymorphism
.
Now we will look at an example in an OOP
environment. Here we will create a class
that contains an identifier name of the method
that is redefined multiple times.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<span class="token keyword">class</span> <span class="token class-name">Main</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">main</span> <span class="token punctuation">(</span> <span class="token class-name">String</span> args <span class="token punctuation">[</span> <span class="token punctuation">]</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token class-name">Utility</span> intel <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Utility</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">int</span> total <span class="token operator">=</span> intel <span class="token punctuation">.</span> add <span class="token punctuation">(</span> <span class="token number">1</span> <span class="token punctuation">,</span> <span class="token number">2</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token class-name">System</span> <span class="token punctuation">.</span> out <span class="token punctuation">.</span> println <span class="token punctuation">(</span> <span class="token string">"add (int, int) = "</span> <span class="token operator">+</span> total <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token class-name">String</span> message <span class="token operator">=</span> intel <span class="token punctuation">.</span> <span class="token function">add</span> <span class="token punctuation">(</span> <span class="token string">"String"</span> <span class="token punctuation">,</span> <span class="token string">"Concatenation"</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token class-name">System</span> <span class="token punctuation">.</span> out <span class="token punctuation">.</span> println <span class="token punctuation">(</span> <span class="token string">"add (String, String) = "</span> <span class="token operator">+</span> message <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">//. Main</span> <span class="token keyword">class</span> <span class="token class-name">Utility</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">int</span> add <span class="token punctuation">(</span> <span class="token keyword">int</span> a <span class="token punctuation">,</span> <span class="token keyword">int</span> b <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> a <span class="token operator">+</span> b <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token class-name">String</span> add <span class="token punctuation">(</span> <span class="token class-name">String</span> a <span class="token punctuation">,</span> <span class="token class-name">String</span> b <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> a <span class="token operator">+</span> <span class="token string">" "</span> <span class="token operator">+</span> b <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">//. Shape</span> |
1 2 3 |
int add (int, int) = 3 String add (String, String) = String Concatenation |
In the environment of stating-typing
typed languages such as Java
, C#
, etc., each identifier consists of the name of the sub-program
and elements that type the input/parameters
values and values. returns output/return
as described in the console
results – called a signature
.
The signature
will be stored by the compilers of each language to distinguish between different versions of the definition, and to choose the appropriate definition in the location where the sub-program
is used. In addition, the operation of redefining a sub-program
many times is called overload
.
So we’ve seen intel
use different sets of mindset
logic when performing add
operations on different data objects: When add
int
integers, it’s the math operator doing the sum; When add
String
strings, it is the writer who does the work of linking the sentences. These are different morphemes represented by the same identifier add
– which is a manifestation of Ad-hoc
Polymorphism
.
In dynamic-typing
languages like JavaScript
, Python
, Ruby
, etc., this representation is done by the coder will have to create their own logic that checks the number of input parameters, the data type. of each parameter, and the sort order of the parameters passed to the sub-program
, to generate logic that forks to other sub-program
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<span class="token keyword">const</span> <span class="token function-variable function">typed</span> <span class="token operator">=</span> <span class="token punctuation">(</span> <span class="token parameter">value <span class="token punctuation">,</span> type</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span> <span class="token keyword">typeof</span> value <span class="token punctuation">)</span> <span class="token operator">==</span> type <span class="token keyword">const</span> <span class="token function-variable function">addNumber</span> <span class="token operator">=</span> <span class="token punctuation">(</span> <span class="token parameter">a <span class="token punctuation">,</span> b</span> <span class="token punctuation">)</span> <span class="token operator">=></span> a <span class="token operator">+</span> b <span class="token keyword">const</span> <span class="token function-variable function">addString</span> <span class="token operator">=</span> <span class="token punctuation">(</span> <span class="token parameter">a <span class="token punctuation">,</span> b</span> <span class="token punctuation">)</span> <span class="token operator">=></span> a <span class="token operator">+</span> <span class="token string">' '</span> <span class="token operator">+</span> b <span class="token keyword">const</span> <span class="token function-variable function">add</span> <span class="token operator">=</span> <span class="token punctuation">(</span> <span class="token parameter"><span class="token operator">...</span> parameters</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">var</span> <span class="token punctuation">[</span> a <span class="token punctuation">,</span> b <span class="token punctuation">]</span> <span class="token operator">=</span> parameters <span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> <span class="token function">typed</span> <span class="token punctuation">(</span> a <span class="token punctuation">,</span> <span class="token string">"number"</span> <span class="token punctuation">)</span> <span class="token operator">&&</span> <span class="token function">typed</span> <span class="token punctuation">(</span> b <span class="token punctuation">,</span> <span class="token string">"number"</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token function">addNumber</span> <span class="token punctuation">(</span> a <span class="token punctuation">,</span> b <span class="token punctuation">)</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> <span class="token function">typed</span> <span class="token punctuation">(</span> a <span class="token punctuation">,</span> <span class="token string">"string"</span> <span class="token punctuation">)</span> <span class="token operator">&&</span> <span class="token function">typed</span> <span class="token punctuation">(</span> b <span class="token punctuation">,</span> <span class="token string">"string"</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token function">addString</span> <span class="token punctuation">(</span> a <span class="token punctuation">,</span> b <span class="token punctuation">)</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> <span class="token string">"any-other-case"</span> <span class="token punctuation">)</span> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">Error</span> <span class="token punctuation">(</span> <span class="token string">"Unsupported Signature"</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment">// - main - - - - - - - - -</span> <span class="token keyword">var</span> total <span class="token operator">=</span> <span class="token function">add</span> <span class="token punctuation">(</span> <span class="token number">1</span> <span class="token punctuation">,</span> <span class="token number">2</span> <span class="token punctuation">)</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> <span class="token string">"add : (number,number) -> number = "</span> <span class="token operator">+</span> total <span class="token punctuation">)</span> <span class="token keyword">var</span> message <span class="token operator">=</span> <span class="token function">add</span> <span class="token punctuation">(</span> <span class="token string">"String"</span> <span class="token punctuation">,</span> <span class="token string">"Concatenation"</span> <span class="token punctuation">)</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> <span class="token string">"add : (string,string) -> string = "</span> <span class="token operator">+</span> message <span class="token punctuation">)</span> |
For the overload
case, it is much more convenient to use static-typing
languages because the type checking of input parameters is supported by the compiler. However, as we have seen, the flexibility of dynamic-typing
always makes anything possible.
Parametric Polymorphism
Parametric
– When the code does not specify a concrete data type and instead abstract symbols are used as a substitute for the ability to accept any data type.
Read the definition and you will see clearly, Parametric Polymorphism
is a feature that should be expressed by coders in static-typing
languages like Java
, C#
, etc. dynamic-typing
like JavaScript
, Python
, Ruby
, etc. is natural by default. So we don’t have to worry about it.
In case you want to learn examples of Parametric Polymorphism
in statically typed languages, you can ask Google with keyword Generic Programming
. Here, we will leave our attention to the next property Abstraction
.
(unpublished) [JavaScript] Lesson 29 – Abstraction in OOP