30/09/2018, 16:43

Virtual và virtual=0?

Mọi người cho em hỏi là giữa

virtual void display();

virtual void display()=0; 

có gì khác nhau vậy ?

lúc nghe giảng thì thấy có nói là pure gì gì đó (nói nhanh quá em nghe ko kịp)
mong mọi người giúp đỡ

Nguyễn Minh Dũng viết 18:56 ngày 30/09/2018

ngôn ngữ gì thế @butobino15? Nếu là C++ thì khai báo virtual void display()=0; bắt buộc class nào kế thừa từ class phải hiện thực hàm display()

Còn nếu không có khai báo =0 thì không cần thiết phải hiện thực hàm display().

Mục đích của việc =0 là để ép buộc lập trình viên phải nhớ và hiện thực hàm display bởi hàm này là hàm thuần ảo pure virtual. Nếu không hiện thực thì mai mốt sẽ gặp lỗi, tìm bug rất mệt.

Đồng thời cũng đánh tiếng cho lập trình viên hiểu đây là một hàm thuần ảo.

Bùi Trung Thông viết 18:57 ngày 30/09/2018

nếu là c++ thì mình có thế giải thích (mới học luôn )

virtual void display();

thằng này theo mình biết là được khai báo ở lớp cha (base class), khi tới lớp con kế thừa từ cha (sub class) thì nó có thể ghi đè lên được (override) và che dấu đi hàm này ở lớp cha. (hành động của thằng con muốn làm)

virtual void display()=0;

hàm này là hàm thuần ảo (pure virtual), lớp chứa nó cũng là lớp thuần ảo (abstrac class), khi kế thừa từ lớp cha, ở lớp con mới định nghĩa lại hàm này với chức năng cụ thể mà ở lớp cha không rõ là sẽ làm gì, ví dụ có lớp Người có hàm tính lương (lúc này đâu biết tính lương làm sao, nên chỉ để đó có cái để lớp con tận dụng ), có lớp học sinhcông nhân kế thừa từ lớp người, thì lúc này ta định nghĩa lại hàm tính lương ở lớp công nhânhọc sinh theo 1 cách nào đó mà chúng ta cần .
nếu có sai sót gì nhờ anh @ltd sửa hộ để em thuộc bài

Itachi Citus viết 18:53 ngày 30/09/2018

Về việc kế thừa: Thực chất dù có virtual hay không virtual thì lớp con đều có thể ghi đè lên (override) bất kỳ một hàm nào của lớp cha. Vấn đề chỉ xảy ra khi bạn sử dụng đa hình (polymophism).
Giả sử như sau:

class A{
    public: void display(){printf("a\n");}
}

class B: public A{
    public: void display(){printf("b\n");}
}

void main(){
    A a;
    B b;
    a.display();
    b.display();
    A *p;
    p = new B();
    p -> display();
}

Khi đó kết quả sẽ là

a
b
a

Khi có virtual:

class A{
    public: virtual void display(){printf("a\n");}
}

Kết quả sẽ là:

a
b
b

Còn về việc virtual = 0

class A{
    public: virtual void display()=0;
}

Khi đó, bạn định nghĩa một hàm thuần ảo không có thân hàm (body), không có nội dung xử lý (lưu ý các hàm virtual ở các ví dụ trước đều phải viết nội dung xử lý của hàm). Khi đó, lớp A sẽ là lớp trừu tượng (abstract class) và bạn không được phép tạo đối tượng / thực thể (instance) của lớp A (Chẳng hạn new A() sẽ báo lỗi). Các lớp kế thừa nó, nếu không viết lại (override) hàm display thì sẽ tiếp tục là lớp trừu tượng, cho tới khi có một lớp kế thừa và viết lại hàm display.

Ngoài lề: Một class chỉ có các hàm thuần ảo được gọi là interface. Vấn đề về abstract class, interface dùng để làm gì thì khi học một xíu nữa về thiết kế hướng đối tượng, mẫu thiết kế bạn sẽ thấy rõ ứng dụng của nó hơn.

Bài liên quan
0