Managing Instance Types Rules
Learn the steps to make the returned instance the same type as the instance on which the method is called.
We'll cover the following...
Sticking to the base type
We’ll create a base class and a derived class and learn ways to manage the types of instances the base methods create.
Example
Let’s start with a class named Names
and a derived SpecializedNames
class.
'use strict';//START:CLASSESclass Names {constructor(...names) {this.names = names;}}//END:CLASSESclass SpecializedNames extends Names {}
The base class constructor receives a rest parameter of names and stores that into a field named names
. The derived class does not have any methods, and its default constructor will faithfully pass parameters to its base class.
filter()
method
Let’s implement a filter1()
method, in the Names
class, that will return an instance with only selected names.
filter1(selector) {
return new Names(...this.names.filter(selector));
}
The filter1()
method receives a function reference, selector
, as a parameter. It passes the reference to the filter()
method of the names
array and, finally, creates an instance of Names
using the result of the call to filter()
. The filter1()
method hardcoded the class name in new Names()
. Therefore, the instance returned by filter1()
will be an instance of Names
even if the method is called on the derived instance.
Sticking to the base type in action
Let’s verify this.
'use strict';class Names {constructor(...names) {this.names = names;}//START:FILTER1filter1(selector) {return new Names(...this.names.filter(selector));}//END:FILTER1}class SpecializedNames extends Names {}//START:USE1const specializedNames = new SpecializedNames('Java', 'C#', 'JavaScript');console.log(specializedNames.filter1(name => name.startsWith('Java')));//END:USE1
We created an instance specializedNames
of SpecializedNames
, invoked the filter1()
method on that instance, and printed the response ...