See the inheritance example from the playground on the TypeScript site:
class Animal {
public name;
constructor(name) {
this.name = name;
}
move(meters) {
alert(this.name + " moved " + meters + "m.");
}
}
class Snake extends Animal {
constructor(name) {
super(name);
}
move() {
alert("Slithering...");
super.move(5);
}
}
class Horse extends Animal {
constructor(name) {
super(name);
}
move() {
alert(super.name + " is Galloping...");
super.move(45);
}
}
var sam = new Snake("Sammy the Python");
var tom: Animal = new Horse("Tommy the Palomino");
sam.move();
tom.move(34);
I have changed one line of code: the alert in Horse.move()
. There I want to access super.name
, but that returns just undefined
. IntelliSense is suggesting that I can use it and TypeScript compiles fine, but it does not work.
Any ideas?
You can use both a structure and a class as base classes in the base list of a derived class declaration: If the derived class is declared with the keyword class , the default access specifier in its base list specifiers is private .
A base class's private members are never accessible directly from a derived class, but can be accessed through calls to the public and protected members of the base class.
Protected members in a class are similar to private members as they cannot be accessed from outside the class. But they can be accessed by derived classes or child classes while private members cannot.
Explanation: The friend function of a class can access the non-private members of base class. The reason behind is that the members of base class gets derived into the derived class and hence become members of derived class too. Hence a friend function can access all of those.
Working example. Notes below.
class Animal {
constructor(public name) {
}
move(meters) {
alert(this.name + " moved " + meters + "m.");
}
}
class Snake extends Animal {
move() {
alert(this.name + " is Slithering...");
super.move(5);
}
}
class Horse extends Animal {
move() {
alert(this.name + " is Galloping...");
super.move(45);
}
}
var sam = new Snake("Sammy the Python");
var tom: Animal = new Horse("Tommy the Palomino");
sam.move();
tom.move(34);
You don't need to manually assign the name to a public variable. Using public name
in the constructor definition does this for you.
You don't need to call super(name)
from the specialised classes.
Using this.name
works.
Notes on use of super
.
This is covered in more detail in section 4.9.2 of the language specification.
The behaviour of the classes inheriting from Animal
is not dissimilar to the behaviour in other languages. You need to specify the super
keyword in order to avoid confusion between a specialised function and the base class function. For example, if you called move()
or this.move()
you would be dealing with the specialised Snake
or Horse
function, so using super.move()
explicitly calls the base class function.
There is no confusion of properties, as they are the properties of the instance. There is no difference between super.name
and this.name
- there is simply this.name
. Otherwise you could create a Horse that had different names depending on whether you were in the specialized class or the base class.
You're using the keywords super
and this
incorrectly. Below is an example that demonstrates them being correctly.
class Animal {
public name: string;
constructor(name: string) {
this.name = name;
}
move(meters: number) {
console.log(this.name + " moved " + meters + "m.");
}
}
class Horse extends Animal {
move() {
console.log(super.name + " is Galloping...");
console.log(this.name + " is Galloping...");
super.move(45);
}
}
var tom: Animal = new Horse("Tommy the Palomino");
Animal.prototype.name = 'horseee';
tom.move(34);
// Outputs:
// horseee is Galloping...
// Tommy the Palomino is Galloping...
// Tommy the Palomino moved 45m.
The first logs the dynamic value for super.name
which is proceeded by the static string value "is Galloping..."
. The keyword this
references the "prototype chain" of the object tom
, and not the object tom
self. Because we have added a name property on the Animal.prototype
, horse will be outputted.
The second log outputs this.name
, the this
keyword refers to the the tom object itself.
The third log is logged using the move
method of the Animal base class. This method is called from Horse class move method with the syntax super.move(45);
. Using the super
keyword in this context will look for a move
method on the prototype chain which is found on the Animal prototype.
Remember TS still uses prototypes under the hood and the class
and extends
keywords are just syntactic sugar over prototypical inheritance.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With