Hi, I would like to know how to call a proc in Base class in a derived class ? For the sake of clarity, i have included some VB.NET code. this is my intention. See this.
Public Class Animal() '// A Base class
Public Weight_of_Animal As Integer
Private Overridable Sub Cry() '// This proc can be call from derived class
Console.WriteLine("Animal is crying...")
End Sub
Public Sub New() '// Base constructor
Weight_of_Animal = 0
End Sub
End Class
Public Class Dog() : Inherits Animal '// A child class Which derived from base class.
Public Name As String
Public Sub New(Byval sName As String = "") '// Child class constructor.
Name = sName
End Sub
Public Overrides Sub Cry() '// Here we are overriding a base class method
MyBase.Cry()
Console.WriteLine("But Dog is barking...")
End Sub
End Class
'// Usage
Dim myAnimal As Dog = New Dog() '// I have init a dog class.
myAnimal.Cry() '// called the derived class method.
'// Output
Animal is crying...
But Dog is barking...
Please show me how to do this in nim ?jlp765, I think that link and your post is not that helpful for his question.
I think question is more related to "super" methods as it is called for example in Ruby.
For Nim we have the procCall defined in module system, I think it may be applied for this case, but I have never tried, as I have not yet done OOP in Nim. Maybe the blog posts of Mr Goran Krampe are helpful, but they are from 2014, I have never read them again since then. I guess procCall may be used to call the base class method, but what when we have an Object of type C, which is derived from type B, which is again derived from base Type A. So we have object of type C and want to call method defined for type B?
You can convert before calling:
type
Animal = ref object of RootObj
Dog = ref object of Animal
proc cry(x: Animal) {.base.} = echo "Foobar"
proc cry(x: Dog) = echo "Bark"
let x = Dog()
x.cry
x.Animal.cry
Here is your example translated to Nim using a method for "cry".
type
Animal* = ref object of RootObj
weightOfAnimal*: int
method cry(x: Animal) {.base.} =
echo "Animal is crying..."
type Dog* = ref object of Animal
name*: string
proc newDog*(sName: string = ""): Dog =
new(result)
result.name = sName
method cry*(x: Dog) =
procCall x.Animal.cry()
echo "But Dog is barking..."
let myAnimal1 = newDog()
let myAnimal2 = Dog(name: "Médor")
myAnimal1.cry
myAnimal2.cry
Some explanations. I have used ref objects but could have used object instead. The only reason here is for convenience as I can use a proc "newDog" to create Dog objects.
There is no use for a proc "newAnimal" as the standard way to create Animal objects is sufficient (weight is initialized at 0 anyway). There is no real need for a proc "newDog" here but I have kept it for demonstration purpose.
To call the Animal "cry", you need to use procCall to bypass the dynamic binding. And you need a conversion to Animal of course. This way, you have full control over what you want to call in the class hierarchy.
To create a Dog object, we can use the "newDog" proc or we can simply provide the values of the fields to initialize.
For the name "Médor" for the dog, this is supposed to be a common dog name in French (never encountered a dog with this name though :-)). I don’t know the common dog name in English.
Hope this helps.
@lscrd, Thanks for the reply. But i have one question. What is the meaning of this line ?
new(result)
The result variable is what is returned in every proc. Even when you call return, it maps to return result in the resulting C code.
In this specific case, result has a type of Dog which is a reference to an object. This means that at the start of the proc, result is a nil (null) reference. When you do new(result), you change the result variable to a reference to an allocated Dog. This way you can safely change its content, like set its name without dealing with a nil dereference.