Just like in other aspects of life, or in other jobs, the way our minds work to create a work value can always be divided into two stages:
- Overview, abstraction, planning, etc.
- Specific conduct, details, work execution, etc..
The earliest tools for OOP
, including the class
definition syntax and the Inheritance
, Encapsulation
, and Polymorphism
features belong to the second group of tools. That’s when we write code that describes the detailed operation logic for the program. And now we will talk about the Abstraction
feature, serving the overall design phase of the software to be built.
In Java
and many languages that support OOP
topics, Abstraction
is supported by a pair of tools named: Abstract Class
and Reference Interface
.
Abstract Class
We’ll start by looking at an example with the common class
we already know. Suppose when building a program to simulate the surrounding environment, we have a lot of individuals from different countries. And for the convenience of creating object
that classify individuals by nationality, we will have class
like Vietnamese
, Japanese
, Chinese
, etc..
However, because object
that simulate individuals also have many basic properties in common, in addition to those that are specific to each country. For example name name
, age age
, gender gender
, methods that support get()
, set()
, etc.. So to reduce the amount of repetitive code in the above class
, we will need a super class
of the form. like Person
.
The story now is that we only need the class Person
in order to reduce the amount of repetitive code in the 1001 inherited class
; But our program never has to create an object
directly from the class Person
using the new Person()
operation. Therefore, the class Person
is now understood as a form of Abstract design and creates a Constraint that: all inherited class
will have all the essential common elements.
With such a need to use the class Person
, in languages like Java
, C#
, etc.. we can use the abstract
keyword placed in front of the class
definition, and the compiler will understand that we only use it. use the class Person
for general design purposes and wouldn’t want the new Person()
operation to be available in the detailed logic code anywhere.
1 2 3 4 | <span class="token keyword">abstract</span> <span class="token keyword">class</span> <span class="token class-name">Person</span> <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> |
In addition, the abstract
keyword in Java
can also be attached to the elements of the abstract class
and so these elements will only be declarative, and create constraints so that the inherited class
will have to fully override
the declared essentials.
1 2 3 4 5 6 7 8 9 10 11 12 13 | <span class="token keyword">abstract</span> <span class="token keyword">class</span> <span class="token class-name">Person</span> <span class="token punctuation">{</span> <span class="token keyword">protected</span> <span class="token keyword">abstract</span> <span class="token class-name">String</span> name <span class="token punctuation">;</span> <span class="token keyword">protected</span> <span class="token keyword">abstract</span> <span class="token keyword">int</span> age <span class="token punctuation">;</span> <span class="token keyword">protected</span> <span class="token keyword">abstract</span> <span class="token keyword">int</span> gender <span class="token punctuation">;</span> <span class="token comment">// - - - - - - - - - - - - - - - - - - -</span> <span class="token keyword">public</span> <span class="token keyword">abstract</span> <span class="token class-name">String</span> getName <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">protected</span> <span class="token keyword">abstract</span> <span class="token keyword">void</span> setName <span class="token punctuation">(</span> <span class="token class-name">String</span> name <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token keyword">abstract</span> <span class="token keyword">int</span> getAge <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">protected</span> <span class="token keyword">abstract</span> <span class="token keyword">void</span> setAge <span class="token punctuation">(</span> <span class="token keyword">int</span> age <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token keyword">abstract</span> <span class="token keyword">int</span> getGender <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">protected</span> <span class="token keyword">abstract</span> <span class="token keyword">void</span> setGender <span class="token punctuation">(</span> <span class="token keyword">int</span> gender <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">//. abstract Person</span> |
And so, if in a certain inherited class
there is no code to override
these abstract
elements, when compiling the code we will receive an error message. A very powerful overview design aid.
To bring this feature to JavaScript
, we can handle it similarly to the case of trait
in the article about Inheritance
. However, checking the super class
of an object
is sometimes also used to generate certain code logic. Therefore we should use class
syntax and return null
in constructor
to block the possibility of object
creation by new
implementation.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <span class="token keyword">class</span> <span class="token class-name">AbstractPerson</span> <span class="token punctuation">{</span> name <span class="token operator">=</span> <span class="token string">"Somebody"</span> age <span class="token operator">=</span> <span class="token number">1001</span> gender <span class="token operator">=</span> <span class="token string">"male"</span> <span class="token function">constructor</span> <span class="token punctuation">(</span> <span class="token punctuation">)</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">"AbstractPerson is an abstract class."</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token function">getSomething</span> <span class="token punctuation">(</span> <span class="token punctuation">)</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">"Not overridden."</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token function">setSomething</span> <span class="token punctuation">(</span> <span class="token punctuation">)</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">"Not overridden."</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">//. AbstractPerson</span> <span class="token keyword">class</span> <span class="token class-name">American</span> <span class="token keyword">extends</span> <span class="token class-name">AbstractPerson</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token comment">//. American</span> <span class="token comment">// - main - - - - - - - - - - - -</span> <span class="token keyword">var</span> fred <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">American</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> fred <span class="token punctuation">.</span> <span class="token function">getSomething</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> |
1 2 3 4 5 6 7 8 | node main.js /home/semiart/Documents/main.js:5 getSomething () { throw new Error ("Not overridden.") }, ^ Error: Not overridden. |
Hmm… about locking the new AbstractPerson()
initialization by throw new Error()
in the constructor
is probably not the point. In fact, when using abstract class
in Java
, there will also be many cases of built-in constructor
to reduce the amount of code that has to be written repeatedly in inherited class
. Perhaps we just need to make it an implicit convention when writing our code that we won’t create object
from the new
operation for class
named with the prefix Abstract
.
Interface
Technically, an Interface
is a concise declaration of the components that make up the API
programming interface of a code library
. This tool originally came from a middle-level programming language called C
, where one used header.h
files to declare constants and identifier names of sub-program
provided by a library to build. The code that implements the detailed logic of the sub-program
is then written in other code files implement.c
.
And when brought to Java
, we can see any class
as a library consisting of code that defines the detailed logic of many different elements. Among them, method method
and static
constants are elements that are often grouped into the API
programming interfaces provided by that class
. And for each of these programming interfaces, at the program overview design stage, Java
provides a declarative syntax with the interface
keyword.
1 2 3 4 5 6 | <span class="token keyword">interface</span> <span class="token class-name">Algebra</span> <span class="token punctuation">{</span> <span class="token keyword">int</span> INFINITY <span class="token operator">=</span> <span class="token number">0</span> <span class="token punctuation">;</span> <span class="token keyword">int</span> sumInt <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 punctuation">}</span> |
Then, at the stage of writing code that implements the detailed processing logic, any class
that is defined as having an implements
of the Algebra
interface – will be bound to need to write implementation code for the methods already declared in this interface
; Or, when compiling the code and running the program without writing the full implementation code, we will receive an error message.
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> main <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">Algebra</span> intel <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Math</span> <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">"Unbound: "</span> <span class="token operator">+</span> <span class="token class-name">Math</span> <span class="token punctuation">.</span> INFINITY <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 comment">// -- Algebra - - - - - - - - - - - - - - - - - - -</span> <span class="token keyword">interface</span> <span class="token class-name">Algebra</span> <span class="token punctuation">{</span> <span class="token keyword">int</span> INFINITY <span class="token operator">=</span> <span class="token number">0</span> <span class="token punctuation">;</span> <span class="token keyword">int</span> sumInt <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 punctuation">}</span> <span class="token comment">// -- Math - - - - - - - - - - - - - - - - - - -</span> <span class="token keyword">class</span> <span class="token class-name">Math</span> <span class="token keyword">implements</span> <span class="token class-name">Algebra</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token comment">//. Math</span> |
1 2 3 4 5 6 | Main.java:18: error: Math is not abstract and does not override abstract method sumInt(int,int) in Algebra class Math implements Algebra { ^ 1 error exit status 1 |
In terms of object
reflection and simulation in real life, each of us can handle more than 1 set of tasks in life. For example, during the day, you can be a worker in the labor force such as: Crafts, Construction, Repair, etc.. and at night, you can be a vocational teacher in a middle school. Complementary Teaching Center.
Obviously during each day period and when you are teaching, you will interact with different individuals on different aspects or interfaces. As an employee, you will use certain methods in work and communication that khác biệt
from when you are a person passing on knowledge and experience.
And if you intend to create a program that simulates the surrounding environment, then you will most likely want to create a class Person
like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <span class="token keyword">interface</span> <span class="token class-name">Crafter</span> <span class="token punctuation">{</span> <span class="token class-name">String</span> craft <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token class-name">String</span> discuss <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">void</span> rest <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">interface</span> <span class="token class-name">Teacher</span> <span class="token punctuation">{</span> <span class="token class-name">String</span> teach <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token class-name">String</span> discuss <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">void</span> listen <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">Person</span> <span class="token keyword">implements</span> <span class="token class-name">Worker</span> <span class="token punctuation">,</span> <span class="token class-name">Teacher</span> <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> |
Thus, when interacting with an object
created from the class Person
via the Crafter
interface, access to teach()
will not be available. And the reverse also happens if the reference is passed through the Teacher
interface, the craft()
method will not be available.
1 2 3 4 5 6 7 8 9 10 | <span class="token class-name">Person</span> fred <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Person</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token class-name">Crafter</span> ascrafter <span class="token operator">=</span> fred <span class="token punctuation">;</span> takayama <span class="token punctuation">.</span> teach <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// -- error</span> <span class="token class-name">Teacher</span> asteacher <span class="token operator">=</span> fred <span class="token punctuation">;</span> takayama <span class="token punctuation">.</span> craft <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// -- error</span> |
This feature of limiting interaction via interface
in Java
is called blackbox
. If it’s to bring to JavaScript
, it’s a bit complicated story, and it takes a lot of manipulation to reorganize the object
‘s architecture. We will save this topic for the next article. For now, we will write example code that brings the interface
to JavaScript
.
Pretty much the same way we’ve brought trait
from languages that support the Multi-Inheritance
form into the JavaScript
environment. Here we will create a literal object
representing the interface
and copy the content to the prototype
of the class
to be implemented using the static constructor
.
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 | <span class="token keyword">const</span> InterfaceWorker <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token function">craft</span> <span class="token punctuation">(</span> <span class="token punctuation">)</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">"Not implemented."</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token function">discuss</span> <span class="token punctuation">(</span> <span class="token punctuation">)</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">"Not implemented."</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token function">rest</span> <span class="token punctuation">(</span> <span class="token punctuation">)</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">"Not implemented."</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">//. InterfaceWorker</span> <span class="token keyword">const</span> InterfaceTeacher <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token function">teach</span> <span class="token punctuation">(</span> <span class="token punctuation">)</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">"Not implemented."</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token function">discuss</span> <span class="token punctuation">(</span> <span class="token punctuation">)</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">"Not implemented."</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token function">listen</span> <span class="token punctuation">(</span> <span class="token punctuation">)</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">"Not implemented."</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">//. InterfaceTeacher</span> <span class="token keyword">class</span> <span class="token class-name">Person</span> <span class="token punctuation">{</span> <span class="token keyword">static</span> <span class="token punctuation">{</span> Object <span class="token punctuation">.</span> <span class="token function">assign</span> <span class="token punctuation">(</span> <span class="token class-name">Person</span> <span class="token punctuation">.</span> prototype <span class="token punctuation">,</span> InterfaceWorker <span class="token punctuation">,</span> InterfaceTeacher <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">//. Person</span> <span class="token keyword">var</span> fred <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Person</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> fred <span class="token punctuation">.</span> <span class="token function">craft</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> fred <span class="token punctuation">.</span> <span class="token function">teach</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> |
1 2 3 4 5 6 7 8 | node main.js /home/semiart/Documents/main.js:2 craft () { throw new Error ("Not implemented.") }, ^ Error: Not implemented. |
The limitation in this way is that we will not be able to define constants in the interface
with static
properties like in Java
. And so it would be necessary to use a naming convention to recognize and avoid changing the values of those elements.
Another note is that when using trait
, we need to make sure that the interface
will be applied to the prototype
first.
The reason is because the interface
is the tool used in the overall design phase and will come first to create the binding. The trait
, on the other hand, is a tool used in the detailed implementation code phase and will come later to ensure that if there are elements that have duplicate definitions with the interface
, they will override
the existing constraints.
1 2 3 4 5 6 7 8 9 | <span class="token keyword">class</span> <span class="token class-name">American</span> <span class="token keyword">extends</span> <span class="token class-name">AbstractPerson</span> <span class="token punctuation">{</span> <span class="token keyword">static</span> <span class="token punctuation">{</span> <span class="token comment">// - implements Interfaces</span> Object <span class="token punctuation">.</span> <span class="token function">assign</span> <span class="token punctuation">(</span> <span class="token class-name">American</span> <span class="token punctuation">.</span> prototype <span class="token punctuation">,</span> InterfaceWorker <span class="token punctuation">,</span> InterfaceTeacher <span class="token punctuation">)</span> <span class="token comment">// - uses Traits</span> Object <span class="token punctuation">.</span> <span class="token function">assign</span> <span class="token punctuation">(</span> <span class="token class-name">American</span> <span class="token punctuation">.</span> prototype <span class="token punctuation">,</span> TraitHardWorking <span class="token punctuation">,</span> TraitRunnable <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">//. American</span> |
(unpublished) [JavaScript] Lesson 30 – OOP Another Way