30/09/2018, 20:16

Sự khác biệt giữa phương thức ảo và phương thức trừu tượng

Ai biết giải thích cho em với ạ? Tại vì em thấy 2 cái này hơi giống nhau.

Ngô Doãn Tuấn viết 22:17 ngày 30/09/2018

Câu hỏi của bạn thật sự hết sức trừu tượng và vô cùng ảo diệu
Nên tại hạ dù muốn thảo luận cùng cũng khó lòng mà diễn đạt được

hon viết 22:17 ngày 30/09/2018

:v em mà biết thì đã hỏi hay hơn rồi. Vậy cho em hỏi có cái gì mà chỉ 1 thằng làm được mà thằng còn lại không làm được không. Chứ thấy nó giống nhau quá.

Nguyen Ca viết 22:30 ngày 30/09/2018

Chắc là hỏi abstract với virtual, cái virtual bên C# thì phải, lâu quá quên rồi hình như vitual thì có thể implement ở lớp abstract còn cái kia thì không.
Có ví dụ luôn này:

public abstract class E
{
    public abstract void AbstractMethod(int i);

    public virtual void VirtualMethod(int i)
    {
        // Default implementation which can be overridden by subclasses.
    }
}

public class D : E
{
    public override void AbstractMethod(int i)
    {
        // You HAVE to override this method
    }
    public override void VirtualMethod(int i)
    {
        // You are allowed to override this method.
    }
}
Itachi Citus viết 22:26 ngày 30/09/2018

Ảo là virtual, trừu tượng là abstract phải không bạn? Phương thức trừu tượng thì không có phần cài đặt (Không có thân hàm), yêu cầu lớp con phải cài đặt lại. Phương thức ảo thì đã tồn tại sẳn cài đặt, lớp con có thể cài đặt lại hoặc không tùy vào nhu cầu.

hon viết 22:21 ngày 30/09/2018

Anh nói ngược phải ko :v . Em thấy ví dụ ở trên bảo phải cài đặt lại cho phương thức trừu tượng mà nhỉ ?

Itachi Citus viết 22:25 ngày 30/09/2018

Uhm đúng rồi, sorry bạn

viết 22:33 ngày 30/09/2018

Phương thức ảo thì đã tồn tại sẳn cài đặt, lớp con có thể cài đặt lại hoặc không tùy vào nhu cầu.

Thế nó khác gì với method thường ạ?

Itachi Citus viết 22:24 ngày 30/09/2018

Khi nào bạn học tới hướng đối tượng, kế thừa là biết à , nó liên quan đến mấy cái đó nên hơi khó giải thích.

Phan Hoàng viết 22:33 ngày 30/09/2018

Cái này liên quan tới khái niệm đa hình (polymorphism, giống kiểu transformer robốt biến hình ý) trong OOP. Nếu bạn từ java sang thì có thể hơi khó hiểu vì Java nó implement mặc định (C++ và C# thì phân biệt cái này rõ ràng hơn)

class Human {
   public void pee() {Console.WriteLine("Pee pee ..."); }
}

class Man : Human {
   public void pee() {Console.WriteLine("Stand pee ...");}
   public void  shit() {Console.WriteLine("Sit shit ..."); }
}

Giờ bạn gọi thế này

Human b = new Human(); b.pee(); //output: Pea pea ..., giả sử là em bé đi tè nhé
Man m = new Man(); m.pee(); //output: Stand pee ...
Human k = new Man(); k.shit(); //fail mặc dù k là Man, nhưng hiện đang trong hình dáng là Human, mà Human chưa có function này 

OK, vì b và m đều hiện giờ có hình dáng (form) là Human và Man tương ứng nên compiler nó hiểu và gọi đúng override function. Còn k dù là Man, nhưng vì đang ở hình dáng Human nên k biết đi i … (kiểu thiểu năng ý, có thể nằm và … ^^)

Tuy nhiên nếu giờ có một function thế này trong Human

void Foo(Human h){ h.pee();}

Nếu giờ gọi:

Human a = new Human(); a.Foo(); //output: Pee pee ...
Man n = new Man(); n.Foo(); //output: Pee pee ...

Tuy có hình dáng là Man, nhưng khi truyền vào Foo() lại chuyển sang hình dáng là Human, vậy nên nó sẽ gọi cái nào? Theo như output thì nó sẽ gọi cái pee của Human. Giờ muốn nó gọi cái pee của Man thì phải làm sao -> giải pháp, khai báo cái pee() trong Human là virtual (hàm ảo, vì thực ra hàm này sẽ k được gọi dù hình dáng là Human bởi sang các class con, đã có hàm này riêng rồi)

Trong java, không cần khai báo virtual, nó cũng gọi override function.

Phan Hoàng viết 22:17 ngày 30/09/2018

Còn khái niệm abstract thì là trừu tượng (có nghĩa là mình không hiểu gì cả, lơ mơ, không rõ ràng, mình chỉ biết tên function như vậy, còn nó hoạt động bên trong thế nào … thì tớ chịu).

Ví dụ như, bạn biết là cần đi pee(), nhưng cơ chế tạo ra pee water, rồi tại sao lại có nó, trong pee water có những chất gì, hàm lượng thành phần ra sao thì … chịu. Cái này cũng trong Polymorphism nhé…

class Human {
   public void abstract pee();
   public void  shit() {Console.WriteLine("Sit shit ..."); }
}

class Man : Human {
   public void pee() {Console.WriteLine("Stand pee ...");}
}

class Woman : Human {
   public void pee() {Console.WriteLine("Sit pee ...");}
}

Giờ bạn có;

Human  b = new Man();
b.pee(); //bạn chỉ cần biết là Man này có thể đi tè (dù đang ở form Human), chứ còn đứng hay ngồi, k cần biết

ArrayList<Human> list = new ArrayList();
list.Add(new Man());
list.Add(new Woman());
foreach (int h in list){
   h.pee();
}

Output:
Stand pee …
Sit pee …

Bài liên quan
0