As we learned in the chapter on subtype polymorphism, an operation defined for a supertype can be safely substituted with its subtypes. As a result, operations defined for ‘Animal’ objects can safely accept ‘Cat’ or ‘Dog’ objects.
Furthermore, we mentioned that you should not confuse subtyping with inheritance. Subtyping describes relationships between types, whereas inheritance is concerned with implementations. This distinction becomes clear with interfaces.
Interfaces are similar to the abstract classes and methods we just learned about, except that all the “methods” of an interface are abstract. An interface contains no implementations.
Interfaces specify types, but they do not specify implementations. Let’s take a transportation analogy. You need to get from San Francisco to Los Angeles. You might not care how you get there, you just need a mode of transport. Interfaces don’t define the “how” so the interface in this case would be the “mode of transport.” The “how” would be implemented in classes like ‘Train’, ‘Car’, ‘Airplane’, or ‘Bus’. As long as the “mode of transport” can move, it should meet your needs. However, you can’t ride an abstract “mode of transport;” you need a ‘Car’, ‘Train’, ‘Airplane’, or ‘Bus’.
To visualize these relationships:
interface IModeOfTransport
{
void move();
}
class Car : IModeOfTransport
{
override void move() {
// ...
}
}
class Train : IModeOfTransport
{
override void move() {
// ...
}
}
class Airplane : IModeOfTransport
{
override void move() {
// ...
}
}
class Bus : IModeOfTransport
{
override void move() {
// ...
}
}
Each concrete class moves differently. For example, a ‘Car’ will have a very different implementation for the ‘move’ method than an ‘Airplane’ because airplanes can fly.
From these relationships, you should be able to understand you can instantiate one of the classes above, such as ‘Car’, like this:
Car rentalCar = new Car();
Let’s say you’re developing a travel website. You want to provide the user several options of getting from San Francisco to Los Angeles. In this case, you might want to generalize the type:
IModeOfTransport transport = new Car();
Now, when the user selects a different option (other than ‘Car’), you can easily change the type of data held in the ‘transport’ variable to an instance of ‘Train’, ‘Plane’, or ‘Bus’.
However, you also recognize that you cannot get from San Francisco to Los Angeles by way of “mode of transport.” You have to specify what kind of mode of transport. Thus, you should recognize this will result in a compiler error:
IModeOfTransport transport = new IModeOfTransport();
Therefore, we use interfaces only to specify types and type relationships. Interfaces do not provide implementations so they cannot be instantiated.
Equipped with this understanding, we can change our ‘Animal’ type relationships. First, let’s start off with a very basic example. Some of our animals lack color. It’s just a black-and-white web page right now. Let’s add a bit of color.
Navigate to your OOP project’s ‘src/Animals/’ folder containing Animal.jspp, Cat.jspp, Dog.jspp, etc. Inside this folder, create a new file named IColorizable.jspp. Inside IColorizable.jspp, let’s enter this code:
module Animals
{
interface IColorizable
{
void colorize();
}
}
The first thing you’ll notice is that we prefixed our interface name with “I” (capital “i”). This is known as a naming convention. Naming conventions help us to name classes, interfaces, modules, functions, and variables that will be consistent with the names used by other programmers that join our team, other third-party libraries, and so on. In JS++, it is typical to prefix interface names with the letter “I” (capital “i”).
Notice how we don’t need the ‘abstract’ modifier. All method signatures inside an interface are considered abstract because implementations are not allowed inside an interface.
Next, we have to specify which classes share a relationship with IColorizable. For now, let’s give only the ‘Dog’ class some color:
import Externals.DOM;
external $;
module Animals
{
class Dog : Animal, IColorizable
{
string _name;
Dog(string name) {
super("icofont-animal-dog");
_name = name;
}
final void render() {
$element.attr("title", _name);
super.render();
}
final void talk() {
alert("Woof!");
}
final void colorize() {
$element.css("color", "brown");
}
}
}
Now, we have to call the colorize() method on our ‘Dog’ instance. Edit main.jspp:
import Animals;
external $;
IColorizable fido = new Dog("Fido");
fido.colorize();
Animal[] animals = [
new Cat("Kitty"),
new Cat("Kat"),
fido,
new Panda(),
new Rhino()
];
foreach(Animal animal in animals) {
animal.render();
}
$("#content").append("<p>Number of animals: " + Animal.getCount().toString() + "</p>");
Try to compile. You’ll get an error:
[ ERROR ] JSPPE5034: Could not determine type for array literal. All elements in array literal must be the same, a mixture of primitive types, or descendants of the same base class at line 8 char 19 at main.jspp
The reason this happens is because the ‘fido’ variable is of type ‘IColorizable’. Meanwhile, the array only accepts elements of type ‘Animal’. If you’ll recall, our ‘Dog’ class inherits directly from ‘IColorizable’ while our ‘Animal’ base class does not. Therefore, we cannot insert an object of ‘IColorizable’ directly into an array of type ‘Animal’; otherwise, we would be able to perform unsafe operations as in JavaScript.

Notice, in the chart, that there is no type relationship between ‘Animal’ and ‘IColorizable’.
There are multiple ways to fix this problem. We’ll fix it by making all our animals colorizable. Edit Dog.jspp and remove the type relationship to ‘IColorizable’. However, keep the method implementation for ‘colorize’. You’ll see why later. Here’s a visualization of what you have to remove in Dog.jspp:
import Externals.DOM;
external $;
module Animals
{
class Dog : Animal, IColorizable
{
string _name;
Dog(string name) {
super("icofont-animal-dog");
_name = name;
}
final void render() {
$element.attr("title", _name);
super.render();
}
final void talk() {
alert("Woof!");
}
final void colorize() {
$element.css("color", "brown");
}
}
}
Now open Animal.jspp and add:
external $;
module Animals
{
abstract class Animal : IColorizable
{
protected var $element;
private static unsigned int count = 0;
protected Animal(string iconClassName) {
string elementHTML = makeElementHTML(iconClassName);
$element = $(elementHTML);
attachEvents();
Animal.count++;
}
public static unsigned int getCount() {
return Animal.count;
}
public virtual void render() {
$("#content").append($element);
}
public abstract void colorize();
public abstract void talk();
private void attachEvents() {
$element.click(talk);
}
private string makeElementHTML(string iconClassName) {
string result = '<div class="animal">';
result += '<i class="icofont ' + iconClassName + '"></i>';
result += "</div>";
return result;
}
}
}
Since our ‘Animal’ class is ‘abstract’, we don’t need to “implement” the ‘colorize’ method. Instead, we just defer it a step further to the derived classes of ‘Animal’ by declaring the ‘colorize’ method as ‘abstract’. Remember how we did not remove the ‘colorize’ method from the ‘Dog’ class? This is why. We’ve delegated the responsibility of implementing ‘colorize’ to the derived classes of ‘Animal’, but we’ve still been able to describe a type relationship between ‘Animal’ and ‘IColorizable’ where ‘IColorizable’ is a supertype of ‘Animal’.
Now, we just need to add colors to the rest of our animals. I’ll keep it brief. Here’s a template for the kind of code you need to add to ‘Cat.jspp’, ‘Panda.jspp’, and ‘Rhino.jspp’:
final void colorize() {
$element.css("color", colorName);
}
Replace ‘colorName’ with the color you want to make the animal. Make your cats “gold”, pandas “black”, and rhinos “silver”.
Edit main.jspp:
import Animals;
external $;
Animal[] animals = [
new Cat("Kitty"),
new Cat("Kat"),
new Dog("Fido"),
new Panda(),
new Rhino()
];
foreach(Animal animal in animals) {
animal.colorize();
animal.render();
}
$("#content").append("<p>Number of animals: " + Animal.getCount().toString() + "</p>");
Compile:
$ js++ src/ -o build/app.jspp.js
Open index.html. The result should look like this:

Similar Reads
JS++ | Inheritance
So far, the only type of animal we've defined is a cat (via the 'Cat' class). Our 'Cat' class also requires us to name our cats. Finally, our 'Cat' class performs rendering to the web page. However, what if we wanted to introduce other animals? How should we implement dogs, pandas, and rhinos? While
3 min read
JS++ | Constructors
In our cat example, we've been able to instantiate our cat and provide a name separately. However, it may be desirable to require the cat to be named at instantiation so that we don't accidentally forget to name a cat. Constructors allow us to control instantiation. By default, JS++ provides a const
3 min read
JS++ | Functions
A function is a section of code which contains a set of instructions, where the instructions describe how a particular task is to be accomplished. Functions are declared and may then be called one or more times. Declaring a function involves specifying the instructions that the function will contain
10 min read
JS++ | Fields and Methods
Creating and Rendering an Animal Open 'src/Animals/Cat.jspp' and enter the following code: external $; module Animals { class Cat { void render() { var $element = $( """ <div class="animal"> <i class="icofont icofont-animal-cat"></i> </div> """ ); $("#content").append($elemen
9 min read
JS++ | Types in JavaScript
In this chapter, we're going to explore JavaScript programming styles and how developers worked with types in JavaScript (rather than JS++). This chapter will help you understand the next chapters which explain the JS++ type system in detail. In this tutorial, we will be using the Google Chrome web
10 min read
Difference between C++ and JavaScript
1. C++ :C++ or CPP is a general-purpose statically typed object-oriented programming language. In 1980, C++ was developed by Bjarne Stroustrup at bell laboratories of AT&T (American Telephone & Telegraph) as an extension to the C language. This seed has expanded since then and had become one
3 min read
JS++ | Upcasting and Downcasting
Now that we understand both subtyping and static versus dynamic polymorphism, we can learn about upcasting and downcasting. Upcasting and downcasting is based on type relationships. In other words, if you have data of type 'Animal', you can "downcast" it to its subtype 'Dog'. Conversely, if you have
3 min read
JS++ | Loops
It often happens in computer programming that you want a piece of code to execute more than once. Loops are programming statements that allow you to handle such cases. JS++ contains loops of various kinds, and we will look at several of them in this tutorial. We will begin, however, by examining two
9 min read
JS++ | Classes, OOP, and User-defined Types
Up until now, we've been declaring variables, looping over data, and writing 'if' and other conditional statements. These operations comprise the "imperative programming" paradigm where we describe "how" a program operates step by step (or, more specifically, statement by statement). Oftentimes, in
6 min read
JS++ | How to install JS++ on different Operating Systems
To use JS++, the first step is to install it on your computer. Go to the JS++ home page at www.onux.com/jspp and click on the "Install Now" button. The website will detect which kind of operating system your computer uses (Windows, Mac OS, or Linux), so when you click on the install button, youâll g
2 min read