I was working through the code examples from the chapter on Traits in Programming in Scala Edition1 https://www.artima.com/pins1ed/traits.html
and came across a weird behavior because of my typo. While overriding method of a trait below code snippet doesn't give any compile error although the return types of the overridden method is different Unit
vs String
. But upon calling the method on an object it returns Unit but doesn't print anything.
trait Philosophical {
def philosophize = println("I consume memory, therefore I am!")
}
class Frog extends Philosophical {
override def toString = "green"
override def philosophize = "It aint easy to be " + toString + "!"
}
val frog = new Frog
//frog: Frog = green
frog.philosophize
// no message printed on console
val f = frog.philosophize
//f: Unit = ()
But when I give the explicit return type in the overridden method , it gives a compile error:
class Frog extends Philosophical {
override def toString = "green"
override def philosophize: String = "It aint easy to be " + toString + "!"
}
override def philosophize: String = "It aint easy to be " + toString +
^
On line 3: error: incompatible type in overriding
def philosophize: Unit (defined in trait Philosophical);
found : => String
required: => Unit
Can anyone help explain why no compile error in the first case.
This means an overridden method may have a more specific return type. That is, as long as the new return type is assignable to the return type of the method you are overriding, it's allowed.
In another words, a method in a subclass can return an object whose type is a subclass of the type returned by the method with the same signature in the superclass. Show activity on this post.
But the limitations are that the overridden method must have a return type that is more specific type of the return type of the actual method. All the answers have given examples of the overridden method to have a return type which is a subclass of the return type of the actual method.
Because a method is overridden in the derived class from the base class. A non-virtual or a static method can’t be overridden. Both the override method and the virtual method must have the same access level modifier. Writing code in comment? Please use ide.geeksforgeeks.org , generate link and share the link here.
When the expected type is Unit
, any value can be accepted:
Value Discarding
If
e
has some value type and the expected type isUnit
,e
is converted to the expected type by embedding it in the term{ e; () }
.
my question is why it got through the compiler in the 1st case
When you did not specify the return type explicitly it was inferred by the type it needs to have for the override
to work.
That turned out to be Unit
.
Since String
values (the value of the expression making up the function body) can be assigned to Unit
, the compiler is happy.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With