There is a task T under object C, object B and C are in the same level under object A. How could object B call the task T under object C when timeout?
Thanks in advance.
Normal methods cannot be accessed outside its scope.
However if you have static method defined in, say class C. To access this method in class B, use scope resolution "::" operator with class name.
For e.g. to access static "display" method from class C to class B,
class B;
function void display();
C::display();
endfunction
endclass
Related
I came across about abstract class in systemverilog when I googling.
But I didn't get it exactly why do we need about abstract class in systemverilog.
So Would you please help me to understand about abstract class in system verilog? Why do we need it, when do we need it.
An abstract class is designed to be extended and cannot be instantiated. Abstract classes are useful to define a contract for extended classes (i.e. extended classes must implement specific functions) in addition to providing existing functionality that can be reused or overridden. pure virtual functions are un-implemented in an abstract class, but must be implemented in extended classes (forming a contract).
Example:
virtual class animal;
// Implemented functionality that can be overridden in extended classes or used as-is
virtual function int get_legs();
return 4;
endfunction
// Functions that must be implemented by extended classes
pure virtual function string get_sound();
pure virtual function string get_name();
endclass
class cat extends animal;
virtual function string get_sound();
return "meow";
endfunction
virtual function string get_name();
return "Mog";
endfunction
endclass
class dog extends animal;
virtual function string get_sound();
return "woof";
endfunction
virtual function string get_name();
return "Rover";
endfunction
endclass
class duck extends animal;
// override default functionality
virtual function int get_legs();
return 2;
endfunction
virtual function string get_sound();
return "quack";
endfunction
virtual function string get_name();
return "Feathers";
endfunction
endclass
module my_module;
initial begin
animal animals[$];
cat c;
dog d;
duck du;
c = new();
d = new();
du = new();
animals.push_back(c);
animals.push_back(d);
animals.push_back(du);
foreach(animals[a])
begin
$display("%s has %0d legs and makes the sound %s",
animals[a].get_name(), animals[a].get_legs(), animals[a].get_sound());
end
end
endmodule
If you are using UVM, uvm_subscriber is a SystemVerilog example of an abstract class (where the write function must be implemented in extended classes).
I have written the following code:
class a {
object c {
var a = "STATIC"
def m() = print("STATIC METHOD")
var f = () => print("STATIC FUNCTION")
}
}
object m {
def main(args: Array[String]) = {
var o = new a()
o.c.m()
}
}
Can I say that the variables, functions and methods that are declared in object c can be static?
If I change name of object c with a then will the object becomes a companion object?
Scala has no true meaning of 'static' that Java does.
The fact that objects have a backing on the JVM that uses static methods / fields is a leaking implementation detail that you only need to deal with if using Java/JVM interop.
Unless you explicitly need that interop, you need to stop thinking of declared objects as 'static' and instead think of them as singletons within their given scope.
An inner object nested under a class, means that there is only ever going to be 1 instance of that object, for each class instance, unlike inner classes which could have multiple instances.
This applies at the top level as well, except that Scala can do additional compatibility with other JVM languages, and mark some of the methods/members as static.
Fields and methods in an object are how Scala declares things that you would have used static for in Java. I guess you can, for intuition sake, say that those fields are usually static (as in only one of those in a JVM at once).
However, in your example, you put an object inside a class, making it no longer static. You can easily check this with a few lines of code (that you can find here on Scastie).
class MyClass {
object Embedded {
val a = "field"
def m = println("method")
}
}
val a = new MyClass().Embedded
val b = new MyClass().Embedded
// prints "a and b are different objects"
if (a eq b)
println("a and b are the same object")
else
println("a and b are different objects")
Regarding your second question: no, class and object must be in the same scope in order for it to be a companion object. You can find more details on the Scala Language Specification.
I quote from there:
Generally, a companion module of a class is an object which has the same name as the class and is defined in the same scope and compilation unit. Conversely, the class is called the companion class of the module.
To answer you questions:
The methods and fields in a.c are not globally static because they need an instance of a to exist. If a were an object, a.c would be static too.
If you want to have a companion object with static fields and methods for your class a it has to be defined outside of a's code block, like this:
class a {
/* non-static stuff goes here */
}
object a {
/* static stuff goes there */
def m() = print("STATIC METHOD")
}
You must keep both in the same file, defining the object or the
class first doesn't matter, so it generally depend on a convention or what makes most sense depending on use case.
If you want to call the static method a.m inside the class a, you will still need to call it a.m and not just m. But the class a will be able to use private fields and methods of object a, because they are companions.
As others already said, static doesn't really exist in Scala, but the concept transpires from Java since Scala is in most cases compiled into java bytecode.
Last advice, the convention is usually the same in Scala and in Java for classes and object: the first-letter of their name should be uppercase (except in some advanced Scala cases)
In Scala Language Spec. I found that
A different form of qualification is protected[this]. A member M marked with this modifier is called object-protected; it can be accessed only from within the object in which it is defined. That is, a selection p.M is only legal if the prefix is this or O.this, for some class O enclosing the reference. In addition, the restrictions for unqualified protected apply.
However I understand the case with this
e.g
this.protectedMember
But what I didn't get is
O.this, for some class O enclosing the reference .
please Help..
However as my understanding says that this is something that is realted with inner class as we do in Swing to get the outer class object eg
OuterClass.this.someMethod in anonymous inner class.
The expression C.this is legal in the statement part of an enclosing class or object definition with simple name C. It stands for the object being defined by the innermost such definition.
E.g. you can have
class O {
class I {
// O.this is the instance of O this I instance is nested in
def M = ...
M // calls M in I
O.this.M // calls M in O
}
protected[this] def M = ...
}
class A(object):
def foo(self):
print 'A'
class B(A):
def foo(self):
print 'B'
class C(B):
pass
c = C()
c.foo()
>>> B
I want to call the foo() method of class A. So how can I call this foo() method so that it will print 'A'
To directly answer your question, you could define C like this:
class C(B):
def foo(self):
A.foo(self)
However, a better question might be: why are you trying to do this? A class needing to access functions from the, erm, "grandparent" that were also defined in the parent class is a pretty good sign that your inheritance model is not ideal. For example: does C need anything from B; could it inherit directly from A?
I just ran into a difficulty while learning Scala. I have an inheritance hierarchy that is essentially equivalent to this:
class A {
protected def myMethod() = println("myMethod() from A")
}
class B extends A {
def invokeMyMethod(a: A) = a.myMethod()
}
But trying to compile this sample, I get the error "test.scala:7: error: method myMethod cannot be accessed in A".
Coming from Java, my understanding is that protected members should be accessible at any point from a derived class, and nowhere have I seen anything that tells me that protected members in Scala are limited by instance. Does anyone have an explanation for this?
Quoting the Scala Language Specification:
A protected identifier x may be used as a member name in a selection r .x
only if one of the following applies:
– The access is within the template defining the member, or, if a qualification C is given, inside the package C, or the class C, or its companion module, or
– r is one of the reserved words this and super, or
– r ’s type conforms to a type-instance of the class which contains the access.
These three rules define when exactly an instance is allowed to access another instance's protected members. One thing that's interesting to note is that, by the last rule, when B extends A, an instance of A may access protected members of a different instance of B... but an instance of B may not access protected members of another A! In other words:
class A {
protected val aMember = "a"
def accessBMember(b: B) = b.bMember // legal!
}
class B extends A {
protected val bMember = "b"
def accessAMember(a: A) = a.aMember // illegal!
}