Hiển thị kết quả từ 1 đến 5 / 5
  1. #1
    Tham gia
    16-07-2002
    Location
    Ha Noi
    Bài viết
    1,282
    Like
    0
    Thanked 0 Times in 0 Posts

    [Q] new, virtual và override trong C#

    Giả sử mình có class Window và class Button như trong hai trừong hợp sau:
    Code:
    public class Window
    {
      public void DrawWindow()
      {
        //........
      }
    }
    
    public class Button:Window
    {
      public new void DrawWindow()
      {
        base.DrawWindow();
        //.......
      }
    }

    Code:
    public class Window
    {
      public virtual void DrawWindow()
      {
        //.....
      }
    }
    
    public class Button:Window
    {
      public override void DrawWindow()
      {
        base.DrawWindow();
        //.....
      }
    }
    Vậy sự khác nhau giữa hai cách implemention này là gì?

    Ở cách thứ hai, nếu sử dụng:
    Code:
    public class Button:Window
    {
      public new virtual void DrawWindow()
      {
        //.......
      }
    }
    thì khi code như sau:
    Code:
    Button button = new Button();
    Window wbutton = new Button();
    button.DrawWindow();
    wbutton.DrawWindow();
    thì DrawWindow() nào được gọi? có gì khác so với sử dụng override không? Nếu có thì khác nhau như thế nào vậy?
    Cảm ơn mọi ý kiến
    Quote Quote

  2. #2
    Tham gia
    10-02-2003
    Bài viết
    69
    Like
    0
    Thanked 0 Times in 0 Posts
    1. khi không cho rằng overriding method DrawWindow là cần thiết (method DrawWindow của bạn là okie rồi), thì khai báo như đoạn code 1 của bạn :
    Code:
    class Window {
       public void DrawWindow() { // stuff };
    }
    mọi object Obj kiểu Window, khi invoke Obj.DrawWindow() sẽ luôn được CLR thực thi Window.DrawWindow().

    @ ở class Button, thực ra không cần keyword new (sẽ nhận được một warning từ compiler - hình như thế ). Keyword new là một cách để bạn khẳng định với compiler rằng method Button.DrawWindow không có liên hệ đa hình đa hiếc gì đến method cùng tên của class Window, và bạn kiểm soát được sự trùng tên của 2 methodz (compiler sợ bạn bị nhầm lẫn nên xuất warning để cho bạn cơ hội xác nhận mưu đồ của bản thân).

    2. keyword virtual là đèn xanh cho overriding method (từ đó -> polymorphism), thế nên, đoạn code 2 mang ý nghĩa đa hình. Để hiểu rõ, ta xem ví dụ của bạn :
    Code:
    Button button = new Button();
    Window wbutton = new Button(); 
    /*
    wbutton IS-A reference which can reference to 
    any Window object (certainly including any Button object,
    'coz Button is derived from Window). Currently, it's 
    referencing to a Button object, rite ?
    */
    button.DrawWindow(); // Button.DrawWindow() is called.
    wbutton.DrawWindow(); // Button.DrawWindow() is called.
    vì wbutton là một tham chiếu kiểu Window, nên khi thấy wbutton.DrawWindow(), CLR sẽ dò đến method Window.DrawWindow trước. Tuy nhiên :

    .thứ nhất : do method Window.DrawWindow có flag virtual được bật lên (nôm na là cho phép ngó tiếp xuống sub-class dưới nếu có thể)...
    .thứ hai : bản thân wbutton đang trỏ tới một object kiểu Button thứ thiệt (Button vốn là sub-class của Window), và method Button.DrawWindow có flag override được bật...

    nên CLR sẽ thực thi method Button.DrawWindow.

    @ trong trường hợp method Button.DrawWindow không có keyword new hay override, hình như sẽ nhận được warning. Nếu bất chấp warning, effect sẽ tương được với trường hợp từ khoá new được đặt vào.

    p/s : không được rõ ràng cho lắm và cũng chưa chắc... chính xác, nhưng thông cảm nha, xót tiền net quá nên làm lẹ lẹ . Tốt nhất là nên check lại. Hehehe...
    Được sửa bởi consoilangthang lúc 18:06 ngày 12-02-2003

  3. #3
    Tham gia
    03-10-2009
    Bài viết
    3
    Like
    0
    Thanked 0 Times in 0 Posts
    Sao tui không hiểu gì hết vậy !!!!

  4. #4
    Tham gia
    30-03-2006
    Bài viết
    197
    Like
    10
    Thanked 2 Times in 2 Posts
    tui cũng chả hỉu gì hết

  5. #5
    Tham gia
    11-05-2011
    Bài viết
    146
    Like
    0
    Thanked 11 Times in 11 Posts
    Các từ khóa virtual được sử dụng để sửa đổi một method or property được khai báo, trong trường hợp này, method or property được gọi là virtual member. Cách thực thi của virutal member có thể bị thay đổi bằng cách override tại lớp kế thừa

    Khi một virtual method được gọi, hệ thống sẽ kiểm tra xem nó có được override hay không. Nếu có thì nó sẽ thực thi override tại lớp chứa override, nếu không thì nó sẽ thực thi virtual member đã được định nghĩa ngay tại lớp đó.

    Mặc định, các method không được khai báo virtual thì không thể override

    Không thể sử dụng virtual với các từ khóa sau trong quá trình khai báo: static, abstract, override

    Virtual property chạy giống abstract method, ngoại trừ sự khác biệt trong cách khai báo
    Code:
    // cs_virtual_keyword.cs
    // Virtual and override
    using System;
    class TestClass 
    {
       public class Dimensions 
       {
          public const double pi = Math.PI;
          protected double x, y;
          public Dimensions() 
          {
          }
          public Dimensions (double x, double y) 
          {
             this.x = x;
             this.y = y;
          }
    
          public virtual double Area() 
          {
             return x*y;
          }
       }
    
       public class Circle: Dimensions 
       {
          public Circle(double r): base(r, 0) 
          {
          }
    
          public override double Area() 
          { 
             return pi * x * x; 
          }
       }
    
       class Sphere: Dimensions 
       {
          public Sphere(double r): base(r, 0) 
          {
          }
    
          public override double Area()
          {
             return 4 * pi * x * x; 
          }
       }
    
       class Cylinder: Dimensions 
       {
          public Cylinder(double r, double h): base(r, h) 
          {
          }
    
          public override double Area() 
          {
             return 2*pi*x*x + 2*pi*x*y; 
          }
       }
    
       public static void Main()  
       {
          double r = 3.0, h = 5.0;
          Dimensions c = new Circle(r);
          Dimensions s = new Sphere(r);
          Dimensions l = new Cylinder(r, h);
          // Display results:
          Console.WriteLine("Area of Circle   = {0:F2}", c.Area());
          Console.WriteLine("Area of Sphere   = {0:F2}", s.Area());
          Console.WriteLine("Area of Cylinder = {0:F2}", l.Area());
       }
    }
    kết quả:
    Area of Circle = 28.27
    Area of Sphere = 113.10
    Area of Cylinder = 150.80

    trong code của bạn
    ở đoạn 1 là cách override áp dụng cho những method không có từ khóa virtual
    đoạn 2: sử dụng virtual
    đoạn 3: override ở lớp cha và cho phép lớp kế thừa nó override

    cách viết
    Button button = new Button();
    Window wbutton = new Button();
    button.DrawWindow();
    wbutton.DrawWindow();
    đều gọi method DrawWindow() đã được implement ở class Button

Bookmarks

Quy định

  • Bạn không thể tạo chủ đề mới
  • Bạn không thể trả lời bài viết
  • Bạn không thể gửi file đính kèm
  • Bạn không thể sửa bài viết của mình
  •