1

I am trying to make it so that I can have some methods in a JavaScript object be inheritable by a child class, but I don't want to allow the parent class to be instantiated. Here is some code that I wrote to illustrate this:

/**
* Shows how basic abstraction works with JavaScript
*/

//Define the person object with a first name, last name, and an age
function Person(firstName, lastName, age) {
    //Make it so that this object cannot be instantiated by identifying its constructor
    if(this.constructor === Person) {
        throw new Error("Can't instantiate an abstract class of type Person!");
    }

    //Assign instance variables
    this.firstName = firstName;
    this.lastName = lastName;
    this.age = age;

    //Create simple get methods
    this.getName = function(){
         return this.firstName + " " + this.lastName;
    }

    this.getFirstName = function() {
         return this.firstName;
    }

    this.getLastName = function() {
         return this.lastName;
    }

    this.getAge = function() {
         return this.age;
    }
}

//Define the student constructor
function Student(firstName, lastName, age, subject) {
    //Assign the instance variables including the new subject variable
    this.firstName = firstName;
    this.lastName = lastName;
    this.age = age;
    this.subject = subject;

    //Add a new function to get the subject from Student
    this.getSubject = function() {
         return this.subject;
    }
}
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;

//Testing the inheritance
var joe = new Student("Joe", "Shmo", 33, "Computer Science");
console.log("First Name: " + joe.getFirstName()); //The getFirstName() function is defined in the superclass
console.log("Subject: " + joe.getSubject()); //The getSubject() function is defined in the subclass

With this code I get an error when trying to call getFirstName on the Student object joe. It seems that it would be very useful to have getFirstName be inheritable by the subclass.

I really want to be able to define the getName function in the parent class so that I can then just have that functionality inherited by the subclasses such as Student. Is there any way to do that? I would really appreciate any help!

Nick P
  • 347
  • 1
  • 4
  • 13
  • You dont need get methods. Since everything is an object in javascript you can just use `joe.firstName`. You might have a look at http://yehudakatz.com/2011/08/12/understanding-prototypes-in-javascript/, and https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects – Craicerjack May 26 '16 at 16:44
  • The point of the code wasn't to get those values. This is dummy code for another project that I am working on just so that I can understand the abstraction in JavaScript. These methods in my actual code will be operating on data. I just want to be albe to inherit that function from a parent class so that I can call it. Do you know how I might do that? – Nick P May 26 '16 at 16:47

1 Answers1

1

You need to define your methods in the Person prototype, not in an instance of Person. That way they will be copied when you do Object.create(Person.prototype):

/**
* Shows how basic abstraction works with JavaScript
*/

//Define the person object with a first name, last name, and an age
function Person(firstName, lastName, age) {
    //Make it so that this object cannot be instantiated by identifying its constructor
    if(this.constructor === Person) {
        throw new Error("Can't instantiate an abstract class of type Person!");
    }

    //Assign instance variables
    this.firstName = firstName;
    this.lastName = lastName;
    this.age = age;

}

Person.prototype.getName = function(){
  return this.firstName + " " + this.lastName;
}

Person.prototype.getFirstName = function() {
  return this.firstName;
}

Person.prototype.getLastName = function() {
  return this.lastName;
}

Person.prototype.getAge = function() {
  return this.age;
}

//Define the student constructor
function Student(firstName, lastName, age, subject) {
    //Assign the instance variables including the new subject variable
    this.firstName = firstName;
    this.lastName = lastName;
    this.age = age;
    this.subject = subject;

    //Add a new function to get the subject from Student
    this.getSubject = function() {
         return this.subject;
    }
}
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;

//Testing the inheritance
var joe = new Student("Joe", "Shmo", 33, "Computer Science");
console.log("First Name: " + joe.getFirstName()); //The getFirstName() function is defined in the superclass
console.log("Subject: " + joe.getSubject()); //The getSubject() function is defined in the subclass
juvian
  • 15,875
  • 2
  • 37
  • 38
  • I see what you changed here, and I thank you for your help. I still don't understand how defining these functions in the person prototype is different than what I did. What is the purpose of the prototype? – Nick P May 26 '16 at 17:10
  • If you make an array of 100000 Persons, with the prototype way the functions will be created only once. If you add them from the constructor, they are just functions you are creating inside your object which is a Person. So they are created 100000 times. Here is a better explanation: http://stackoverflow.com/questions/9772307/declaring-javascript-object-method-in-constructor-function-vs-in-prototype/9772864#9772864 . In the this way they are just local functions to your particular instance of the object, so they are not inherited – juvian May 26 '16 at 17:16