Why results differs w/ and w/o declaring virtual methods in extended class

I cannot quite understand why these two cases yield different results:

  1. In extended class, virtual method is defined
  2. In extended class, virtual method is NOT defined.

In detail, the situation and source code is shown below. Points here are:

  1. Object handler’s type is BaseClass, which points to ExtendClass (i.e. casting is used)
  2. In the method, class variable (A, B) is referred.

Method::printA()/printB() displaying class variable(int A, B) are declared in the class.
As the contents in these functions are the same for both Base and Extended Class,
I omit overriding printA(), which gives different results compared to printB().


module tb();
class BasePacket;
  int A; //1;
  int B; // 2;

  function new(int A=1, int B=2);
     this.A=A;
     this.B=B;
  endfunction

  virtual function void printA;
     $display("[%m] A is %0d", A);
  endfunction
  virtual function void printB;
     $display("[%m] B is %0d", B);
  endfunction : printB
endclass : BasePacket
class My_Packet extends BasePacket;
  int     A; // 3
  int 	   B; // 4

  function new(int A=3, int B=4);
     this.A=A;
     this.B=B;
  endfunction

  /* -----\/----- EXCLUDED -----\/-----
  virtual function void printA;
     $display("A is %0d", A);
  endfunction
   -----/\----- EXCLUDED -----/\----- */
  virtual function void printB;
     $display("[%m] B is %0d", B);
  endfunction : printB
endclass : My_Packet

  initial begin
     BasePacket P1;
     My_Packet P2  = new;

     P1 = P2;   // P1 has a handle to a My_packet object
     P1.printA; // A is 1
     P1.printB; // B is 4
  end
endmodule // tb

Thanks

In reply to tsb_matumoto:

The reason for this is that you have defined A and B in your base and extended classes. This is rather tricky and not a recommended practice. In this case an object from the extended class will have “A”, “B”, “super.A”, “super.B”. A method in the base class, virtual or not, that is not overridden will access variables in the base class, they cannot access variables in the derived class. So “P1.printA” will access “super.A” which has a value of “1”. While “P1.printB” since it was overridden, will access “B” which has a value of “4”.

So as a remedy, remove duplicate definitions of properties in the extended class.


class My_Packet extends BasePacket;
  //int     A; //--COMMENT OUT--
  //int     B; //--COMMENT OUT--

In reply to ayehia:

Thank you very much. Now I understood what happened with my code!
I will make it a rule to avoid declaring same variable in Extended Class.