Accessing the Object Itself
All OOP-supported programming languages have a special keyword or way to access the "self" object from within a class. For Java and C++, it is this
. For Python, it can be named anything but is by convention self
.
Suppose you are creating a constructor for the Rectangle
class which will take the parameters height
and width
. You can define the constructor like below:
1class Rectangle extends Shape {
2 constructor(h, w) {
3 super();
4 this.height = h;
5 this.width = w;
6 }
7}
But what if you wanted to name the parameters the same thing as the attributes of the class? It would be easier for the user of the class to understand the method signature Rectangle(int height, int width)
instead of Rectangle(int h, int w)
. However, after renaming the parameters, if we use the identifier height
or width
inside the function, then it will always refer to the parameter (closest scope) and not the attributes. So how do we refer to attributes with the same name?
Here we can use the this
keyword to refer to anything of "this" class and not anything outside of the class. See the code below:
1class Rectangle extends Shape {
2 constructor(height, width) {
3 super();
4 // this.height => height attribute of Rectangle.
5 // height => height parameter of the constructor method.
6 this.height = height;
7 this.width = width;
8 }
9}
In addition to referencing attributes with the same name as parameters, you also have to access the object itself in order to pass an object to an outside function from within the class. For example, suppose you have a class named GetOne
whose job is to return one Rectangle
object from two Rectangle objects. Additionally, suppose you have a method in Rectangle
that takes a GetOne
class and a Rectangle
object then updates itself to become a copy of the returned object. Let us first define the GetOne
class hierarchy.
1class GetOne {
2 get(rect1, rect2) {
3 // Just return the first one for now.
4 return rect1;
5 }
6}
7
8class GetSmallerArea extends GetOne {
9 get(rect1, rect2) {
10 return rect1.getArea() <= rect2.getArea() ? rect1 : rect2;
11 }
12}
13
14class GetLargerArea extends GetOne {
15 get(rect1, rect2) {
16 return rect1.getArea() < rect2.getArea() ? rect2 : rect1;
17 }
18}
Note: In Go, there's no concept of class inheritance like in Java. Instead, Go uses composition and embedding. The given Go code assumes a struct named Rectangle
exists with a method getArea
.
Now we define the method inside the Rectangle
class. The method will take GetOne
and another Rectangle
object then update itself using get
methods. For this, we need to pass two objects to the get
method. One object will be the Rectangle and the other will be itself. See below how we can do that:
1class Rectangle extends Shape {
2 constructor(height, width) {
3 super();
4 this.height = height;
5 this.width = width;
6 }
7
8 compareAndUpdate(comparator, other) {
9 // Passing myself to comparator with "this" keyword
10 let one = comparator.get(this, other);
11 this.height = one.height;
12 this.width = one.width;
13 }
14
15 toString() {
16 return `Rectangle(${this.height},${this.width})`;
17 }
18}
In the main method, we can use this like below:
1// Assuming necessary class definitions from previous conversions
2const main = () => {
3 // Using concept of polymorphism
4 let smaller = new GetSmallerArea();
5 let larger = new GetLargerArea();
6
7 let rect1 = new Rectangle(3, 4);
8 let rect2 = new Rectangle(5, 6);
9
10 rect1.compareAndUpdate(smaller, rect2);
11 console.log(rect1.toString()); // Rectangle(3,4)
12
13 rect1.compareAndUpdate(larger, rect2);
14 console.log(rect1.toString()); // Rectangle(5,6)
15}
16
17main();