In a class-based object-oriented language, in general, state is carried by instances, methods are carried by classes, and inheritance is only of structure and behaviour. In ECMAScript, the state and methods are carried by objects, while structure, behaviour, and state are all inherited.
This is the snippet from ECMAScript Specification June 2015. I don't understant parts of this text.
- State is carried by instances - what does state mean in this context and example of this (c++ is preferred)
- Methods are carried by classes - this probably means , that if I want to know object's methods , I need to look at the class of that object.
- Inheritance is only of structure and behaviour - only structure and behaviour is inherited?
- And so on...
Can anyone please explain this in details? examples would be great.
Object-oriented systems are one where we keep the programs and the data together - so that the way of handling a piece of data is kept together with the data itself, encapsulated together in an object.
There are generally two types of object-oriented languages. Class-based languages and prototyped languages. In a Class-based languages, the behaviour of the objects, and the definition of the data they will hold, is defined in a Class or a Class definition. The Classes do very little work other than that. Objects are created as little worker bee copies of the Class, and they do as the Class has defined them as doing. These instance objects do the vast bulk of the actual work.
In prototyped languages, there is no separate thing holding the definition of what the object does. The object in question holds it's own definitions.
State is just a fancy way of saying the data. More precisely, it's the value of the attributes of the object at an exact given moment in time.
Methods is just a contraction of "the object's method of responding to a message".
If the original developers of object-orientation had talked about "the object's way of responding to a message" we'd be talking about "ways" nowadays. (If they'd said they created particular categories of things, then we'd now have Thing-Oriented Development, and we'd have Category-based thing-oriented languages and prototype-based thing-oriented languages. The point is, don't get hung up about the language. But I digress).
So... let's have some examples. Modern Object-orientation comes from Xerox Corporation's Palo Alto Research Center (known as PARC). So I'll use examples from there.
Smalltalk is the King Daddy of object-oriented languages. (Simula had done some pioneering in this field, and was a strong influence on the early versions of Smalltalk, even up to Smalltalk-72. But Smalltalk and object-orientation, as we know it today, really arrives with Smalltalk-80).
Smalltalk is a Class-based language.
You define a Class. Say, the Class 'Person'. We need to store some data. Let's go with "Given name", "Family name", "Date of Birth", and "Full name". These definitions are stored in the Class.
We'll also define a message protocol - the list of messages that an object of Class Person knows how to respond to. Then we define a method of responding to each message. These definitions get stored in the Class. When
aPerson
(i.e an instance ofClass
Person
, which is the same as an object belonging to Class Person, with the name aPerson) needs to respond to the message, it looks up the method of responding in the Class definitions. (The class is itself an object instance of Class Metaclass, but we'll stay out of that rabbit-hole in this answer).So, you write code. You store it in Class Person.
You define variables. You store the definition of the data structure for each variable in the Class Person.
You create an object that belongs to the Person Class. We'll call it aPerson. The data will get stored in aPerson. The format and structure of the data is defined in the Person Class.
Let's define some methods.
First, we write a method that will create anArbitraryPerson object
This method is defined in the Class. It will be executed by the Class itself. So it is called a class method.
So our first method is a Class method, that creates a new Person object. This new object belongs to that specific Class of objects.
We obviously need a message that can set the first name of an object of Class Person.
We define this method in Class Person. But it will only be used by instances of Class Person.
self
is the object that has received the message. The object looks up this piece of code which is stored as part of Class Person's definitions when it needs to respond to the message known asnamed
.aFirstNameString
is just a placeholder for the parameter or argument that we pass into the method.We define standard getters and setters (aka accessors) for each variable that has its data stored in an object.
.
We can do the same for other instance variables :
familyName
,dateOfBirth
,fullName
.fullName
is a derived attribute ofPerson
. We'll deal with it a little differently, by also giving it an additional methodBecause it is derived, we'll need an additional message to derive it.
So let's use the methods.
(this reads as: assign the result of calling the method "
Person named: 'Tom'
" to anArbitraryPerson )So, if we execute those three statements we end up creating three instance of the Person Class.
The state of their instance variables - i.e. the values that their attributes have been set to - is stored in the object. The method code is stored in the Class. But every object has precisely and only one Class, so that's not a problem. We always know exactly which Class to look-up the method definition in.
If we were to send these messages:
we would have changed the state of each and every one of those objects.
We can look inside the objects and see the data. We have to look intside the Class to see the method definitions. We have to look inside the Class to see the data structure definitions.
You can find more resources at Beginning to Smalltalk (link) and many other fine Smalltalk websites.
So now for prototype-based object-oriented languages. I'll use another OO-language from Xerox Parc - LambdaMoo code.
This was created for permanently-on object database servers. Think erlang-like uptimes. Smalltalk does the same thing - running and running, essentially forever, and accepting all changes to the system while it is running.
We don't refer to any class. We just create the objects directly.
In Lambda, objects have "verbs" and "properties". And the verb definitions and property definitions are stored in the object itself. And the state of the properties - the particular values of the data that the object encapsulates - is stored in the object too.
If we want, we can change all the behaviour on each one (we can override it) - because they are all just objects. And they store their own method code. If the obhject doesn't have a message in its own protocol, it'll ask it's parents and grandparents and great-grandparents, until either of them has a method of dealing with the message, or you run out of ancestors to ask.
For a fuller beginners tutorial to OO more details Yib's Pet Rock - A Programming Primer for Beginners. (link) Part of Yib's Guide to Mooing.
A better approach might be:
Which allows us to send the message to the object, and so invoke the method on the object, and so change the state of the object.
Now we have the methods carried by the objects, along with the attribute definitions. And the state of the data.
In Smalltalk, the classes carried the methods (i.e. the method definitions ) and the attribute definitions. The objects themselves only carried the state of the data.
Okay, I'll take a shot at answering this question.
Background on ECMAScript 6 classes as syntactic sugar
ES6 classes are just syntactic sugar over the ordinary prototypal inheritance found in ECMAScript (aka JavaScript).
This is equivalent to:
Doing inheritance in ES6 is a lot easier than the old method though:
Doing the same in ES5 or earlier is prone to issues, but that is slightly off-topic.
Questions
An instance of a class is an object similar to C++.
Equivalent in C++:
As you can see, the instances of a class behave the same way in ES6 and C++, however there are no literal equivalents to
private
orpublic
encapsulation in ES6.In ECMAScript, you can override functions on an instance of a class, as it is just an object like everything else.
Using
.constructor.prototype
of an object gets the prototype of the object when it has been instantiated with thenew
keyword.It is a cumbersome wording they have chosen. What I believe they mean is that as in ECMAScript, an instance of a class is just another object like anything else, you can modify almost everything about it, while in C++, an instance of a class has stricter requirements. You can't add new methods to an instance, you can't add new properties, and you can't break the constraints that the language has provided for you.
I hope this answers your questions. If anything isn't clear, please comment and I'll edit it.