The object in the below code has been instantiated just once, right? So the single object that has been instantiated should contain a single integer i field whose value is 2. Why does p.i give 1 instead of 2? Is this specific to SystemVerilog? Or do all oop languages behave similarly?
class Packet;
integer i = 1;
function integer get();
get = i;
endfunction
endclass
class LinkedPacket extends Packet;
integer i = 2;
function integer get();
get = -i;
endfunction
endclass
LinkedPacket lp = new;
Packet p = lp;
j = p.i; // j = 1, not 2
j = p.get(); // j = 1, not -1 or –2
Thanks
This example is pasted from section 8.13 of the the 1800-2009 SystemVerilog specification, which explains the issue. My opinion is that overriding class members like this is a really bad idea. The example in the specification is simply there to illustrate how it works.
The class property integer i is defined in both the base class and child class. This declaration in LinkedPacket overrides and hides the declaration in Packet.
From the specification:
In this case, references to p access the methods and class properties of the Packet class. So, for example, if
class properties and methods in LinkedPacket are overridden, these overridden members referred to
through p get the original members in the Packet class. From p, new and all overridden members in
LinkedPacket are now hidden.
Since you are calling the function through a handle to Packet you get the values from Packet.
In addition, the get() function is not declared virtual. This is why you do not see the integer being negated. This is also noted in the example in the specification.
To call the overridden method via a base class object (p in the example), the method needs to be declared
virtual (see 8.19).
This behavior is not unique to SystemVerilog and is similar to what you would observe in other OO languages.
If you want to have a different value for i in LinkedPacket, the proper way to do this would be to only declare i in the base class, and initialize it differently in the constructor.
e.g.
class Packet;
integer i;
function new();
i = 1;
endfunction
virtual function integer get();
get = i;
endfunction
endclass
class LinkedPacket extends Packet;
function new();
i = 2;
endfunction
virtual function integer get();
get = -i;
endfunction
endclass
I'm no SystemVerilog expert, but I'd expect p.i to return 1 as that is what you initialise it to. p.get() is just another way to return the same value, so that will also be 1.
j=get(); will (I think) return -2 - without an object prefix, I'd expect it to call the second function which is outside of the class.
Related
I am programming in Fortran and I need to create an object class that has a dynamic vector as an attribute. Here is a minimal example of what I am trying to achieve.
MODULE my_class
PRIVATE
PUBLIC my_object
! define my object with a dynamic attribute
TYPE my_object
private
integer:: size;
real, allocatable:: tab(:); ! here the dynamic vector
CONTAINS
private
final:: destructor;
END TYPE my_object
! define an interface for object constructor
INTERFACE my_object
module procedure:: constructor;
END INTERFACE my_object
CONTAINS
! define constructor
FUNCTION constructor(size) RESULT(obj)
integer, intent(in):: size;
type(my_object):: obj;
obj%size= size;
allocate(obj%tab(size))
END FUNCTION constructor
! define destructor
SUBROUTINE destructor(this)
class(my_object):: this;
if (allocated(this%tab)) deallocate(this%tab)
END SUBROUTINE
END MODULE my_class
But I am not sure that is the proper way to do it. Is there not a risk of memory leaking with this implementation in case of multiple initializations? With this code for example :
PROGRAM test
USE my_class
IMPLICIT NONE
type(my_object):: obj;
obj= my_object(1000);
obj= my_object(3000);
END PROGRAM test
Has the obj%tab of the first instance been properly deallocated?
Or should I reimplement the equal operator?
Thanks for helping me to find out how Fortran deals with this.
What is 'Access specifier' in Object oriented programming ?
I have searched for it's definition several times but not get the satisfactory answer.
Can anyone please explain it to me with realistic example ?....
Thanks in advance
What are they?
This wikipedia article pretty much sums it up. But Let's elaborate on a few main points. It starts out saying:
Access modifiers (or access specifiers) are keywords in object-oriented languages that set the accessibility of classes, methods, and other members. Access modifiers are a specific part of programming language syntax used to facilitate the encapsulation of components.1
So an Access Specifier aka Access Modifier takes certain class, method, or variable and decides what other classes are allowed to use them. The most common Access Specifiers are Public, Protected, and Private. What these mean can vary depending on what language you are in, but I'm going to use C++ as an example since that's what the article uses.
Accessor Method | Who Can Call It
-----------------------------------------------------------------------
Private | Only the class who created it
Protected | The class who created it and derived classes that "inherit" from this class
Public | Everyone can call it
Why is this important?
A big part of OOP programming is Encapsulation. Access Specifiers allow Encapsulation. Encapsulation lets you choose and pick what classes get access to which parts of the program and a tool to help you modularize your program and separate out the functionality. Encapsulation can make debugging a lot easier. If a variable is returning an unexpected value and you know the variable is private, then you know that only the class that created it is affecting the values, so the issue is internal. Also, it stops other programmers from accidentally changing a variable that can unintentionally disrupt the whole class.
Simple Example
Looking at the example code from the article we see Struct B i added the public in there for clarity:
struct B { // default access modifier inside struct is public
public:
void set_n(int v) { n = v; }
void f() { cout << "B::f" << endl; }
protected:
int m, n; // B::m, B::n are protected
private:
int x;
};
This is what would happen if you created an inherited struct C that would try and use members from struct B
//struct C is going to inherit from struct B
struct C :: B {
public:
void set_m(int v) {m = v} // m is protected, but since C inherits from B
// it is allowed to access m.
void set_x(int v) (x = v) // Error X is a private member of B and
// therefore C can't change it.
};
This is what would happen if my main program where to try and access these members.
int main(){
//Create Struct
B structB;
C structC;
structB.set_n(0); // Good Since set_n is public
structB.f(); // Good Since f() is public
structB.m = 0; // Error because m is a protected member of Struct B
// and the main program does not "inherit" from struct B"
structB.x = 0; // Error because x is a private member of Struct B
structC.set_n() // Inheritied public function from C, Still Good
structC.set_m() // Still Good
structC.m = 0 // Error Main class can't access m because it's protected.
structC.x = 0; // Error still private.
return 0;
}
I could add another example using inheritance. Let me know if you need additional explanation.
Despite using composition over inheritance?
If so, is there any solution for it at the language level?
As VonC wrote, but I'd like to point out something.
The fragile base class problem is often blamed on virtual methods (dynamic dispatch of methods – this means if methods can be overridden, the actual implementation that has to be called in case of such an overridden method can only be decided at runtime).
Why is this a problem? You have a class, you add some methods to it, and if MethodA() calls MethodB(), you can't have any guarantee that the MethodB() you wrote will be called and not some other method of a subclass that overrides your MethodB().
In Go there is embedding, but there is no polymorphism. If you embed a type in a struct, all the methods of the embedded type get promoted and will be in the method set of the wrapper struct type. But you can't "override" the promoted methods. Sure, you can add your own method with the same name, and calling a method by that name on the wrapper struct will invoke your method, but if this method is called from the embedded type, that will not be dispatched to your method, it will still call the "original" method that was defined to the embedded type.
So because of this, I'd say the fragile base class problem is only present in a quite mitigated form in Go.
Example
Demonstrating the problem in Java
Let's see an example. First in Java, because Java "suffers" from this kind of problem. Let's create a simple Counter class and a MyCounter subclass:
class Counter {
int value;
void inc() {
value++;
}
void incBy(int n) {
value += n;
}
}
class MyCounter extends Counter {
void inc() {
incBy(1);
}
}
Instantiating and using MyCounter:
MyCounter m = new MyCounter();
m.inc();
System.out.println(m.value);
m.incBy(2);
System.out.println(m.value);
The output is as expected:
1
3
So far so good. Now if the base class, Counter.incBy() would be changed to this:
void incBy(int n) {
for (; n > 0; n--) {
inc();
}
}
The base class Counter still remains flawless and operational. But the MyCounter becomes malfunctioning: MyCounter.inc() calls Counter.incBy(), which calls inc() but due to dynamic dispatch, it will call MyCounter.inc()... yes... endless loop. Stack overflow error.
Demonstrating the lack of the problem in Go
Now let's see the same example, this time written in Go:
type Counter struct {
value int
}
func (c *Counter) Inc() {
c.value++
}
func (c *Counter) IncBy(n int) {
c.value += n
}
type MyCounter struct {
Counter
}
func (m *MyCounter) Inc() {
m.IncBy(1)
}
Testing it:
m := &MyCounter{}
m.Inc()
fmt.Println(m.value)
m.IncBy(2)
fmt.Println(m.value)
Output is as expected (try it on the Go Playground):
1
3
Now let's change Counter.Inc() the same way we did in the Java example:
func (c *Counter) IncBy(n int) {
for ; n > 0; n-- {
c.Inc()
}
}
It runs perfectly, the output is the same. Try it on the Go Playground.
What happens here is that MyCounter.Inc() will call Counter.IncBy() which will call Inc(), but this Inc() will be Counter.Inc(), so no endless loop here. Counter doesn't even know about MyCounter, it does not have any reference to the embedder MyCounter value.
The Fragile base class problem is when a seemingly safe modifications to a base class, when inherited by the derived classes, may cause the derived classes to malfunction.
As mentioned in this tutorial:
For all intents and purposes, composition by embedding an anonymous type is equivalent to implementation inheritance. An embedded struct is just as fragile as a base class.
I have noticed a situation where there is a class (say: ClassA) with variable declarations and various methods. And in another class (say: Class B), there is a method(MethodofClassB()) with the return type of the method as ClassA.
so it is like:
Class A
{
variable i,j;
public int MethodA()
{
//some operation
}
}
Class B
{
variable x,y;
public static A MethodB()
{
//some operation
return obj;
}
}
1) I understand that MethodB() return an object of ClassA. Waty would be the use(the intention) of returning the object of ClassA
2) What is the reason for defining MethodB() as Public static. what would happen if static was not used for MethodB()
3)What would the returned objct look like. I mean if my method returned an integer, it would return some numerical value say '123' . If a method returns an object of a class, what would be in the returrned value.
please help me understand this with a small example
1) I understand that MethodB() return an object of ClassA. Waty would be the use(the intention) of returning the object of ClassA
Depends on what the method does, which isn't illustrated in this example. If the result of the operation is an instance of A then it stands to reason that it would return an instance of A, whatever A is.
For example, if A is a Car and B is a CarFactory then the method is likely producing a new Car. So it would return a Car that's been produced.
2) What is the reason for defining MethodB() as Public static. what would happen if static was not used for MethodB()
public allows it to be accessed by other objects. static means it's not associated with a particular instance of B. Both are subjective based, again, on the purpose of the method (which isn't defined in the example). Being static, it can be called as such:
var newInstance = B.MethodB();
If it wasn't static then an instance of B would be required:
var objectB = new B();
var newInstance = objectB.MethodB();
There are more and more implications here, including things like memory/resource usage and thread safety. All stemming from the purpose and business logic meaning of what B is and what MethodB does.
3)What would the returned objct look like. I mean if my method returned an integer, it would return some numerical value say '123' . If a method returns an object of a class, what would be in the returrned value.
It would be an instance of A. Similar to creating an instance here:
var objectA = new A();
This method also creates (or in some way gets) an instance:
var objectA = B.MethodB();
Without knowing more about what A is, what its constructor does, and what MethodB does, these two operations are otherwise the same.
First, your code is incorrect. There is no "ClassA" class. The class name is A, so the return type should be A not ClassA.
Second, the standard Java coding standards say to start methods and variables with lower case letters. So, your example should have been:
Class A
{
A anA;
B aB;
public int methodA()
{
//some operation
}
}
Class B
{
SomeType x, y;
public static A methodB()
{
//some operation
return obj;
}
}
David's answer shortly before mine is technically correct on points 1 and 2, although he also uses your mistake of calling the A type ClassA. His code for his answer to point 3, though, is incorrect and misleading. I would change his wording to this:
`3)What would the returned objct look like. I mean if my method returned an
integer, it would return some numerical value say '123' . If a method returns
an object of a class, what would be in the returrned value`.
It would be an instance of class A. Similar to creating an instance here:
A objectA = new A();
This method also creates (or in some way gets) an instance:
A objectA = B.methodB();
Without knowing more about what class A is, what its constructor does, and what methodB does, these two operations are otherwise the same.
When using the -Xcheckinit compiler option and implementing my own readObject method in a serializable class, I can't call any accessor functions on fields declared in the body of my class from the readObject method. Fields declared as constructor arguments are ok. When I do try to access a field declared in the class body, I get a scala.UninitializedFieldError.
That is, the following code fails on println(y) in the readObject method, even after y has been set in the previous line!
#serializable case class XYPointWithRWAndPrint(var x: Int) {
var y = 0
#throws(classOf[java.io.IOException])
private def writeObject(out: java.io.ObjectOutputStream) {
out.writeInt(x)
out.writeInt(y)
}
#throws(classOf[java.io.IOException])
#throws(classOf[ClassNotFoundException])
private def readObject(in: java.io.ObjectInputStream) {
x = in.readInt()
println(x)
y = in.readInt()
println(y)
}
}
Why?
When using the -Xcheckinit compiler option, the compiler creates a bitmap field that it uses to check initialization.
public volatile int bitmap$0;
In the accessors, the compiler checks the bitmap:
public int y(){
if ((this.bitmap$0 & 0x1) != 0){ return this.y; }
throw new UninitializedFieldError("Uninitialized field: Test.scala: 2".toString());
}
In the constructor, the compiler updates the bitmap:
public XYPointWithRW(int x) {
Product.class.$init$(this);
this.y = 0;
this.bitmap$0 |= 1;
}
Note that it doesn't update the bitmap for constructor arguments, only for fields declared in the class body. It does this because it assumes that you will be calling the constructor and that those fields will be initialized immediately.
During deserialization however, the no-arg constructor of the first non-serializable super class is called (Object in this case), instead of the one-arg constructor shown above. Then readObject is called. The constructor above is never called. Therefore, the bitmap is never updated. Calling the accessor would fail anywhere its called, not just in the readObject method.
To work around this, you must update the bitmap manually. I've chosen to do so from the readObject method. I set all of the bits in the bitmap to 1, like so:
getClass.getField("bitmap$0").set(this, -1)
By setting all the bits to 1, it will work for all the fields (up to 32 fields anyway...what happens beyond that is anyones guess).