Error in coverage

I developed a simple coverage for D flip flop.

class coverage_c extends uvm_subscriber#(seq_items);
  
  `uvm_component_utils(coverage_c)
  
  function new(string name, uvm_component parent);
    super.new(name, parent);
    d_cg = new();
  endfunction
  
  seq_items collect;
  
  covergroup d_cg;
    option.per_instance = 1;
    
    d_coverpoint: coverpoint collect.d { bins d0 = {0};
                                        bins d1 = {1};}
    
    q_coverpoint: coverpoint collect.q { bins q0 = {0};
                                        bins q1 = {1};}
    
    rst_coverpoint: coverpoint collect.rst {bins rst0 = {0};
                                            bins rst1 = {1};}
    
  endgroup
  
  virtual function void build_phase(uvm_phase phase);
    collect = seq_items::type_id::create("collect", this);
  endfunction


//Error producing code  
 /* virtual function void write(seq_items tx);
    collect.copy(tx);
    this.d_cg.sample();
  endfunction*/
  
//No error
  virtual function void write(seq_items t);
    collect.copy(t);
    this.d_cg.sample();
  endfunction
    
endclass

When I use some other handle name instead of t for seq_items in the write() parameter, the following error is produced.

ERROR VCP2932 “Invalid virtual method override, method is not identical with method from base class…” “coverage.sv” 25 31

Please help me in solving this issue.

In reply to ViKKi:

The write() function in uvm_subscriber has the signature of:

pure virtual function void write(T t);

SystemVerilog requires your override to match the function signature. The argument names need to match because you can pass arguments by name as well as position order.

Can you please explain how to pass the argument names by position order?

In reply to ViKKi:

When you call any function, you usually use position order

function void f(int a, b);
endfunction
f(x,y);

In position order, x gets copied to a, y gets copied to b.
But you can also do by name

f(.b(x),.a(y));

By name, x gets copied to b, y gets copied to a. This becomes very useful when function arguments have defaults and you only want to pass in a subset of arguments.

function void f(int a=0, b=1,c=2);
endfunction
f(.b(x));

If f were to become a virtual function, the argument names must remain the same so that the name .b can always be found.