This commit is contained in:
Ilya Kantor 2019-10-11 10:00:53 +03:00
parent c3fadb7dc1
commit c9eea4d0bf
3 changed files with 22 additions and 52 deletions

View file

@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="467" height="316" viewBox="0 0 467 316"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><g id="inheritance" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="animal-rabbit-extends.svg"><path id="Rectangle-1" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M242 23h185v64H242z"/><text id="constructor:-Animal" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="252" y="42">constructor: Animal</tspan> <tspan x="252" y="57">run: function</tspan> <tspan x="252" y="72">stop: function</tspan></text><path id="Rectangle-1-Copy" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M242 286h185v28H242z"/><text id="Animal.prototype" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="241" y="15">Animal.prototype</tspan></text><path id="Rectangle-1-Copy-4" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M242 166h185v48H242z"/><text id="constructor:-Rabbit" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="252" y="185">constructor: Rabbit</tspan> <tspan x="252" y="200">hide: function</tspan></text><text id="Rabbit.prototype" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="241" y="158">Rabbit.prototype</tspan></text><path id="Rectangle-1-Copy-2" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M11 23h105v48H11z"/><text id="Animal" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="10" y="15">Animal</tspan></text><path id="Rectangle-1-Copy-3" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M11 166h105v48H11z"/><text id="Rabbit" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="10" y="158">Rabbit</tspan></text><text id="new-Rabbit" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="247" y="278">new Rabbit</tspan></text><path id="Line" fill="#EE6B47" fill-rule="nonzero" d="M330.5 96.5l7 14h-6v28h-2v-28h-6l7-14z"/><path id="Line-Copy" fill="#EE6B47" fill-rule="nonzero" d="M211 40l14 7-14 7v-6h-79v-2h79v-6z"/><text id="[[Prototype]]" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="340" y="120">[[Prototype]]</tspan></text><path id="Line-Copy-3" fill="#EE6B47" fill-rule="nonzero" d="M330.5 230.5l7 14h-6v28h-2v-28h-6l7-14z"/><text id="[[Prototype]]-Copy" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="340" y="254">[[Prototype]]</tspan></text><text id="prototype" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="139" y="35">prototype</tspan></text><path id="Line-Copy-2" fill="#EE6B47" fill-rule="nonzero" d="M211 182l14 7-14 7v-6h-79v-2h79v-6z"/><text id="prototype-copy" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="139" y="176">prototype</tspan></text><text id="name:-&quot;White-Rabbit&quot;" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="253" y="304">name: &quot;White Rabbit&quot;</tspan></text><text id="constructor" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="17" y="41">constructor</tspan></text><text id="constructor-copy" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="17" y="183">constructor</tspan></text></g></g></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="467" height="316" viewBox="0 0 467 316"><defs><style>@import url(https://fonts.googleapis.com/css?family=Open+Sans:bold,italic,bolditalic%7CPT+Mono);@font-face{font-family:&apos;PT Mono&apos;;font-weight:700;font-style:normal;src:local(&apos;PT MonoBold&apos;),url(/font/PTMonoBold.woff2) format(&apos;woff2&apos;),url(/font/PTMonoBold.woff) format(&apos;woff&apos;),url(/font/PTMonoBold.ttf) format(&apos;truetype&apos;)}</style></defs><g id="inheritance" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="animal-rabbit-extends.svg"><path id="Rectangle-1" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M242 23h185v64H242z"/><text id="constructor:-Animal" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="252" y="42">constructor: Animal</tspan> <tspan x="252" y="57">run: function</tspan> <tspan x="252" y="72">stop: function</tspan></text><path id="Rectangle-1-Copy" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M242 286h185v28H242z"/><text id="Animal.prototype" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="241" y="15">Animal.prototype</tspan></text><path id="Rectangle-1-Copy-4" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M242 166h185v48H242z"/><text id="constructor:-Rabbit" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="252" y="185">constructor: Rabbit</tspan> <tspan x="252" y="200">hide: function</tspan></text><text id="Rabbit.prototype" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="241" y="158">Rabbit.prototype</tspan></text><path id="Rectangle-1-Copy-2" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M11 23h105v48H11z"/><text id="Animal" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="10" y="15">Animal</tspan></text><path id="Rectangle-1-Copy-3" fill="#FFF9EB" stroke="#E8C48E" stroke-width="2" d="M11 166h105v48H11z"/><text id="Rabbit" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="10" y="158">Rabbit</tspan></text><text id="new-Rabbit" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="247" y="278">new Rabbit</tspan></text><path id="Line" fill="#EE6B47" fill-rule="nonzero" d="M330.5 96.5l7 14h-6v28h-2v-28h-6l7-14z"/><path id="Line-Copy" fill="#EE6B47" fill-rule="nonzero" d="M211 40l14 7-14 7v-6h-79v-2h79v-6z"/><text id="[[Prototype]]" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="340" y="120">[[Prototype]]</tspan></text><path id="Line-Copy-3" fill="#EE6B47" fill-rule="nonzero" d="M330.5 230.5l7 14h-6v28h-2v-28h-6l7-14z"/><text id="[[Prototype]]-Copy" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="340" y="254">[[Prototype]]</tspan></text><text id="prototype" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="139" y="35">prototype</tspan></text><path id="Line-Copy-2" fill="#EE6B47" fill-rule="nonzero" d="M211 182l14 7-14 7v-6h-79v-2h79v-6z"/><text id="prototype-copy" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="139" y="176">prototype</tspan></text><text id="name:-&quot;White-Rabbit&quot;" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="253" y="304">name: &quot;White Rabbit&quot;</tspan></text><text id="constructor" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="17" y="41">constructor</tspan></text><text id="constructor-copy" fill="#8A704D" font-family="PTMono-Regular, PT Mono" font-size="14" font-weight="normal"><tspan x="17" y="183">constructor</tspan></text><ellipse id="Oval" cx="391.5" cy="117.5" stroke="#EE6B47" rx="70.5" ry="20.5"/></g></g></svg>

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 4 KiB

Before After
Before After

View file

@ -1,9 +1,13 @@
# Class inheritance
Let's say we have two classes.
Class inheritance is a way for one class to extend another class.
`Animal`:
So we can create new functionality on top of the existing.
## The "extends" keyword
Let's say with have class `Animal`:
```js
class Animal {
@ -24,52 +28,19 @@ class Animal {
let animal = new Animal("My animal");
```
Here's how we can represent `animal` object and `Animal` class graphically:
![](rabbit-animal-independent-animal.svg)
...And we would like to create another `class Rabbit`.
...And `Rabbit`:
As rabbits are animals, `Rabbit` class should be based on `Animal`, have access to animal methods.
The syntax to extend another class is: `class Child extends Parent`.
Let's create `class Rabbit` that inherits from `Animal`:
```js
class Rabbit {
constructor(name) {
this.name = name;
}
hide() {
alert(`${this.name} hides!`);
}
}
let rabbit = new Rabbit("My rabbit");
```
![](rabbit-animal-independent-rabbit.svg)
Right now they are fully independent.
But we'd want `Rabbit` to extend `Animal`. In other words, rabbits should be based on animals, have access to methods of `Animal` and extend them with its own methods.
To inherit from another class, we should specify `"extends"` and the parent class before the braces `{..}`.
Here `Rabbit` inherits from `Animal`:
```js run
class Animal {
constructor(name) {
this.speed = 0;
this.name = name;
}
run(speed) {
this.speed += speed;
alert(`${this.name} runs with speed ${this.speed}.`);
}
stop() {
this.speed = 0;
alert(`${this.name} stands still.`);
}
}
// Inherit from Animal by specifying "extends Animal"
*!*
class Rabbit extends Animal {
*/!*
@ -84,14 +55,12 @@ rabbit.run(5); // White Rabbit runs with speed 5.
rabbit.hide(); // White Rabbit hides!
```
Now the `Rabbit` code became a bit shorter, as it uses `Animal` constructor by default, and it also can `run`, as animals do.
Object of `Rabbit` class have access to both `Rabbit` methods, such as `rabbit.hide()`, and also to `Animal` methods, such as `rabbit.run()`.
Internally, `extends` keyword adds `[[Prototype]]` reference from `Rabbit.prototype` to `Animal.prototype`:
Internally, `extends` keyword works using the good old prototype mechanics. It sets `Rabbit.prototype.[[Prototype]]` to `Animal.prototype`. So, if a method is not found in `Rabbit.prototype`, JavaScript takes it from `Animal.prototype`.
![](animal-rabbit-extends.svg)
So, if a method is not found in `Rabbit.prototype`, JavaScript takes it from `Animal.prototype`.
As we can recall from the chapter <info:native-prototypes>, JavaScript uses prototypal inheritance for build-in objects. E.g. `Date.prototype.[[Prototype]]` is `Object.prototype`, so dates have generic object methods.
````smart header="Any expression is allowed after `extends`"
@ -119,19 +88,20 @@ That may be useful for advanced programming patterns when we use functions to ge
## Overriding a method
Now let's move forward and override a method. As of now, `Rabbit` inherits the `stop` method that sets `this.speed = 0` from `Animal`.
Now let's move forward and override a method. By default, all methods that are not specified in `class Rabbit` are taken directly "as is" from `class Animal`.
If we specify our own `stop` in `Rabbit`, then it will be used instead:
But if we specify our own method in `Rabbit`, such as `stop()` then it will be used instead:
```js
class Rabbit extends Animal {
stop() {
// ...this will be used for rabbit.stop()
// ...now this will be used for rabbit.stop()
// instead of stop() from class Animal
}
}
```
...But usually we don't want to totally replace a parent method, but rather to build on top of it to tweak or extend its functionality. We do something in our method, but call the parent method before/after it or in the process.
Usually we don't want to totally replace a parent method, but rather to build on top of it to tweak or extend its functionality. We do something in our method, but call the parent method before/after it or in the process.
Classes provide `"super"` keyword for that.