THÔNG DỤNG
OOP
ES6
ES(X)
CÁC CHỦ ĐỀ
BÀI MỚI NHẤT
Dự án mới của mình là gamehow.net, mời anh em ghé thăm và góp ý ạ.

Extends trong Javascript - kế thừa và ghi đè phương thức

Trong bài này chúng ta sẽ tìm hiểu cách sử dụng từ khóa extends trong Javascript, qua đó sẽ giúp bạn hiểu được tính kế thừa và cách ghi đè phương thức trong js.

Kể từ ES6 thì javascript đã trở thành một ngôn ngữ siêu khó, ta có thể tạo đối tượng bằng nhiều cách khác nhau như function và class. Và với sự ra đời của class thì chúng ta có thêm các khái niệm về tính kế thừa (inheritance) và ghi đè phương thức (overriding).

banquyen png
Bài viết này được đăng tại freetuts.net, không được copy dưới mọi hình thức.

1. Extends trong Javascript là gì?

Trong javascript, extends là một từ khóa dùng để khai báo một lớp được kế thừa từ một lớp khác. Qua đó lớp kế thừa có thể sử dụng những phương thức và thuộc tính của lớp được kế thừa.

Nếu lớp A kế thừa từ lớp B thì lớp A ta gọi là lớp con, còn lớp B ta gọi là lớp cha.

Câu hỏi được đặt ra là tại sao cần tính kế thừa? Câu trả lời như sau:

Thực tế thì nhiều đối tượng có thể có những thuộc tính và hành động giống nhau, và bắt buộc mỗi đối tượng chúng ta phải cài đặt một class riêng lẻ, thì việc kế thừa sẽ giúp cho việc cài đặt các đối tượng trở nên đơn giản hơn.

Ví dụ: Ta có đối tượng động vật, trong động vật lại có nhiều loại động vật khác nhau như sư tử, rùa.

  • Động vật sẽ có các đặc tính như: Số cân, màu lông, chủng loại...
  • Động vật sẽ có các hành động như: Ăn, chạy, săn mồi ...

Những đặc tính và hành động trên cũng có trong hai đối tượng sư tửrùa, vì vậy hai đối tượng này ta sẽ khai báo kế thừa đối tượng động vật.

2. Xây dựng class extends trong javascript

Bây giờ ta sẽ xây dựng ba class như ví dụ mà mình đã nói ở phần 1, bằng cách sử dụng từ khóa extends trong js.

Khai báo lớp Animal.

class Animal {
    constructor(name) {
        this.name = name;
        this.speed = 0; // Tốc độ chạy 0km / h
    }
    run(speed) {
        this.speed = speed;
        alert(`${this.name} chạy tốc độ là ${this.speed}.`);
    }
    stop() {
        this.speed = 0;
        alert(`${this.name} đứng yên.`);
    }
}

Khai báo lớp Lion kế thừa từ lớp Animal: Lion có một đặc tính riêng biệt mà động vật khác không có, đó là Gầm. Vì vậy ngoài các hành động runstop thì mình sẽ khai báo thêm hành động roar.

class Lion extends Animal{
    roar(){
        alert(`${this.name} đang gầm`);
    }
}

let lion = new Lion("Sử tử");
lion.run(80);
lion.stop();
lion.roar();

Khai báo lớp con thỏ kế thừa từ lớp Animal: Con thỏ là một động vật nhỏ bé nên nó hay bị các động vật khác tấn công, vì vậy nó có thêm hành động ẩn nấp.

class Rabbit extends Animal {
  hide() {
    alert(`${this.name} đang ẩn nấp`);
  }
}

let rabbit = new Rabbit("Con thỏ");
rabbit.run(0.05);
rabbit.stop();
rabbit.hide();

Như vậy lớp con sẽ có đầy đủ những phương thức và thuộc tính của lớp cha, đây là một quy tắc hiển nhiên trong việc phân cấp cha con.

Có một vấn đề rất quan trọng trong việc kế thừa, đó là mức độ truy cập đến các thuộc tính và phương thức trong lớp. Vấn đề này mình sẽ trình bày trong bài viết private và protected trong js.

3. Overriding trong Javascript

Overriding là kỹ thuật ghi đè hàm (viết lại phương thức) của lớp cha.

Đôi khi những hành động bên trong lớp cha sẽ không thích ứng với các lớp con, lúc này lớp con có thể ghi đè lại các phương thức của lớp cha thông qua kỹ thuật Overriding.

Ví dụ với lớp con thỏ dưới đây, hành động chạy (run) của nó thường sẽ đi kèm với hành động ẩn nấp (hide). Vì vậy ta có thể viết lại hàm run trong lớp Rabbit như sau:

class Animal {
    constructor(name) {
        this.name = name;
    }
    run() {
        console.log(`${this.name} đang chạy`);
    }
}

class Rabbit extends Animal {
    // Override hàm run
    run(){
        super.run();
        this.hide();
    }
    hide() {
        console.log(`${this.name} đang ẩn nấp`);
    }
}

let rabbit = new Rabbit("Con thỏ");
rabbit.run();

Tòm lại:

  • Trong ví dụ này thì phương thức hide đã bị ghi đè lại vì nó được khai báo ngay trong lớp con.
  • Để gọi đến hàm run ở lớp cha thì ta phải sử dụng từ khóa super, nếu không nó sẽ hiểu là bạn đang gọi đếm hàm run ở lớp con.

4. Overriding constructor javascript

Nếu bạn muốn overriding hàm khởi tạo constructor thì cần chú ý một số vấn đề như sau.

  • Nếu bạn không muốn override hàm constructor thì không phải làm gì cả.
  • Nếu bạn tạo một hàm constructor ở hàm con thì bắt buộc phải sử dụng từ khóa super để gọi đến hàm constructor của lớp cha, và phải đặt vị trí đầu tiên.

Trường hợp này là ok.

class Animal {
    constructor(name) {
        console.log('Hàm khởi tạo lớp cha');
    }
}

class Rabbit extends Animal {

}

let rabbit = new Rabbit();

Trường hợp dưới đây là sai, bởi vì bạn đã tạo một constructor ở lớp con, nên bắt buộc phải sử dụng từ khóa super.

class Animal {
    constructor(name) {
        console.log('Hàm khởi tạo lớp cha');
    }
}

class Rabbit extends Animal {
    constructor(name, age) {
        console.log('Hàm khởi tạo lớp con');
    }
}

Sửa lại như sau:

class Animal {
    constructor(name) {
        console.log('Hàm khởi tạo lớp cha');
    }
}

class Rabbit extends Animal {
    constructor(name, age) {
        super(name);
        console.log('Hàm khởi tạo lớp con');
    }
}

let rabbit = new Rabbit();

Mặc dù hàm cha không có hàm constructor nhưng bạn cũng phải sử dụng từ khóa supper.

class Animal {
}

class Rabbit extends Animal {
    constructor() {
        super();
        console.log('Hàm khởi tạo lớp con');
    }
}

let rabbit = new Rabbit();

Như vậy là mình đã giới thiệu xong từ khóa extends trong javascript, cũng như cách sử dụng nó để tạo ra những lớp kế thừa. Bài này mình xin dừng ở đây, hẹn gặp lại các bạn ở bài tiếp theo.

Cùng chuyên mục:

Cách gộp hai object javascript lại với nhau

Cách gộp hai object javascript lại với nhau

Cách lấy chiều dài của object trong Javascript

Cách lấy chiều dài của object trong Javascript

Hướng dẫn giải phương trình bậc 1 bằng Javascript

Hướng dẫn giải phương trình bậc 1 bằng Javascript

Cách dùng nextSibling trong javascript

Cách dùng nextSibling trong javascript

Cách dùng insertAdjacentHTML trong javascript

Cách dùng insertAdjacentHTML trong javascript

Cách dùng innerHTML trong Javascript

Cách dùng innerHTML trong Javascript

Cách dùng insertBefore trong javascript

Cách dùng insertBefore trong javascript

Cách dùng insertAfter trong Javascript

Cách dùng insertAfter trong Javascript

Cách dùng parentNode trong Javascript

Cách dùng parentNode trong Javascript

Cách dùng parentElement trong Javascript

Cách dùng parentElement trong Javascript

Tính tổng các phần tử trong mảng javascript

Tính tổng các phần tử trong mảng javascript

Tính tổng hai số bằng Javascript (cộng hai số)

Tính tổng hai số bằng Javascript (cộng hai số)

Cách gán giá trị cho thẻ input trong javascript

Cách gán giá trị cho thẻ input trong javascript

Để gán giá trị cho thẻ input thì ta có hai cách, thứ nhất là…

Cách kiểm tra số nguyên âm trong javascript

Cách kiểm tra số nguyên âm trong javascript

Cách kiểm tra số nguyên dương trong javascript

Cách kiểm tra số nguyên dương trong javascript

Hàm closure trong javascript

Hàm closure trong javascript

Closure là một khái niệm không phải ai cũng ..

Biểu thức chính quy RegEx trong Javascript

Biểu thức chính quy RegEx trong Javascript

Bài này chúng ta sẽ tìm hiểu đến chuỗi và cách sử dụng biểu thức…

Cách dùng Import / Export Module trong javascript

Cách dùng Import / Export Module trong javascript

Khi bạn xây dựng một ứng dụng nhỏ thì việc đặt

Cơ chế hoạt động của hoisting trong Javascript

Cơ chế hoạt động của hoisting trong Javascript

Hoisting là vấn đề liên quan đến cách khai báo biến trong Javascript. Nó liên…

Cấp độ private / protected của class trong Javascript

Cấp độ private / protected của class trong Javascript

Top