I have a question concerning Scala override (as my title suggests)
Now I have the following classes/traits:
trait FSM {def transitionGraph:Map[String,(JsValue,FSM)]
abstract class AClass: FSM { def transitionGraph }
class Class extends AClass{ override def transitionGraph ... } <-- Wont work
trait OverrideTrait extends AClass { abstract override def transitionGraph } <-- works
class NewClass extends OverrideTrait { } <--- Works, I can use the overridden transitionGraph
My question is: Why can I not override things from an abstract class. Is it because I am never allowed to instantiate an abstract class. Thus the behavior :
val AClass class = new Class
is never allowed to happen?
Thanks.
There seems to be a lot of stuff omitted from the code you've given, so I'm not sure I get the question, but here's something similar that does compile:
trait FSM { def transitionGraph: String }
abstract class AClass extends FSM { def transitionGraph: String }
class Class extends AClass { override def transitionGraph = ??? }
trait OverrideTrait extends AClass { override def transitionGraph = ??? }
class NewClass extends OverrideTrait { }
Does this help at all?
Your code example wouldn't compile. But it should work once you corrected a few things:
trait FSM {def transitionGraph:Map[String,(JsValue,FSM)]}
abstract class AbstractClass extends FSM { def transitionGraph }
class ConcreteClass extends AbstractClass{ def transitionGraph = ??? }
val someClass: AbstractClass = new ConcreteClass
Related
I thought putting final in Function would stop this issue from happening? I'm not too familiar with Scala. Can someone explain?
Class 'Country must either be declared abstract or implement abstract member 'execute():Object' in path.to.Invokable'
class Country extends MarketFunction("america") {}
abstract class MarketFunction(function: String) extends Function {
...
}
trait Function extends Invokable {
final def execute(): AnyRef = {
// not important
}
}
public interface Invokable {
Object execute();
}
Is it because AnyRef is not a direct comparison to java Object?
This worked for me
class Country extends MarketFunction("america") {}
abstract class MarketFunction(function: String) extends Function[AnyRef] {
...
}
trait Function[A <: AnyRef] extends Invokable {
override final def execute(): A = {
// not important
}
}
public interface Invokable {
Object execute();
}
I have a class that extends a Trait and I want to write Traits that can mix in with the class and override some of the methods.
The trait that my class is extending looks like this
trait CharSource {
def source: Iterator[Char]
def words: Iterator[String] = {
while(source.hasNext){
//Logic to get the next word from a Char Iterator
}
}
final def chars: Iterator[Char] = words.toString().toIterator
}
The class that extends CharSource
class IteratorDocumentSource(iterator: Iterator[Char]) extends CharSource {
def source = iterator
}
Now I want to write a trait to override the source def in IteratorDocutmentSource for some special behavior
trait PunctuationRemover extends Transformer {self: CharSource =>
override
/** Character source. Overriding should be in terms of `super.source` for
stackability. */
abstract val source: Iterator[Char] = {
super.source
//additional logic ...
}
}
The transformer trait that PunctioationRemover extends
trait Transformer {self: CharSource =>
protected def source: Iterator[Char]
def words: Iterator[String]
}
I get an error when making this call
new IteratorDocumentSource("Hello World!".iterator) with PunctuationRemover
Error:
An exception or error caused a run to abort:
SampleSuite$$anonfun$2$$anon$3.document$PunctuationRemover$$super$source()Lscala/collection/Iterator;
java.lang.AbstractMethodError:
SampleSuite$$anonfun$2$$anon$3.document$PunctuationRemover$$super$source()Lscala/collection/Iterator;
I referenced this post but I think my situation is a little different
Can I override a scala class method with a method from a trait?
I have this code which appears over and over in my project for each type of class we serialize to Avro
class FooKryoRegistrator extends KryoRegistrator {
override def registerClasses(kryo: Kryo) {
kryo.register(classOf[Foo], SpecificRecordBinarySerializer(classTag[Foo]))
kryo.register(classOf[GenericData.Array[_]], new SpecificInstanceCollectionSerializer(classOf[java.util.ArrayList[_]]))
}
}
Now instead of having to write this Registrator class for each and every entity (Foo, Bar, Baz.....) in my project, I thought it will be better to make this generic. So I did
class GenericKryoRegistrator[T] extends KryoRegistrator {
override def registerClasses(kryo: Kryo) {
kryo.register(classOf[T], SpecificRecordBinarySerializer(classTag[T]))
kryo.register(classOf[GenericData.Array[_]], new SpecificInstanceCollectionSerializer(classOf[java.util.ArrayList[_]]))
}
}
But I get a compile time error
class type required but T found
I googled on this error and found a recommendation that I should use ClassTag instead of class. So I changed the implementation to
class GenericKryoRegistrator[T] extends KryoRegistrator {
override def registerClasses(kryo: Kryo) {
kryo.register(classTag[T].runtimeClass, SpecificRecordBinarySerializer(classTag[T]))
kryo.register(classOf[GenericData.Array[_]], new SpecificInstanceCollectionSerializer(classOf[java.util.ArrayList[_]]))
}
}
but now it says
No ClassTag available for T
If you take the class tag as an implicit argument to your class, you can then use it:
class GenericKryoRegistrator[T] (implicit ct: ClassTag[T]) extends KryoRegistrator {
override def registerClasses(kryo: Kryo) {
kryo.register(ct.runtimeClass, SpecificRecordBinarySerializer(ct))
kryo.register(classOf[GenericData.Array[_]], new SpecificInstanceCollectionSerializer(classOf[java.util.ArrayList[_]]))
}
}
Assuming I have a simple abstract base class like so:
abstract class MyAbstractBaseClass {
def hello : Unit
}
and then I write a "stacking" trait like so:
trait MyTrait extends MyAbstractBaseClass {
abstract override def hello : Unit =
{
super.hello
println("How are you?");
}
}
then why won't Scala let me define a subclass as follows:
class MyClass extends MyAbstractBaseClass with MyTrait {
override def hello : Unit = println("Hello!")
}
error: overriding method hello in trait MyTrait of type => Unit;
method hello needs `abstract override' modifiers
If I try their suggestion of using 'abstract override':
class MyClass extends MyAbstractBaseClass with MyTrait {
abstract override def hello : Unit = println("Hello!")
}
error: `abstract override' modifier only allowed for members of traits
Can anyone help me understand this?
P.S. I know that the below does work:
class MyClass extends MyAbstractBaseClass {
override def hello : Unit = println("Hello!")
}
val x = new MyClass with MyTrait
x.hello
Hello!
How are you?
but am trying to understand why the former does not.
In summary: why can't I provide an implementation of the abstract base class - while also taking advantage of the trait's functionality?
The trick is that you can't have an "abstract" method in the flow of the linearization, that is called from a super call.
Try this, you will see it compiles:
abstract class MyAbstractBaseClass {
def hello : Unit
}
class SubClass extends MyAbstractBaseClass {
def hello {
println("toto")
}
}
trait MyTrait extends MyAbstractBaseClass {
abstract override def hello : Unit =
{
super.hello
println("How are you?")
}
}
class MyClass extends SubClass with MyTrait { //note the CONCRETE SubClass here
override def hello : Unit = println("Hello!")
}
new MyClass().hello
You got the error, because the compiler starts with MyTrait (at the top of the stack, so the first to be called) and that MyTrait calls through super an abstract method... (of MyAbstractBaseClass) => it crashes since your super call can't target immediately a concrete method.
In my code snippet, you will notice that MyTrait is "at the top" (during linearization) of a concrete Subclass class, that makes the trick.
I have a base abstract class (trait). It has an abstract method foo(). It is extended and implemented by several derived classes. I want to create a trait that can be mixed into the derived classes so that it implements foo() and then calls the derived class's foo().
Something like:
trait Foo {
def foo()
}
trait M extends Foo {
override def foo() {
println("M")
super.foo()
}
}
class FooImpl1 extends Foo {
override def foo() {
println("Impl")
}
}
class FooImpl2 extends FooImpl1 with M
I tried self types and structural types, but I can't get it to work.
You were very close. Add the abstract modifier to M.foo, and you have the 'Stackable Trait' pattern: http://www.artima.com/scalazine/articles/stackable_trait_pattern.html
trait Foo {
def foo()
}
trait M extends Foo {
abstract override def foo() {println("M"); super.foo()}
}
class FooImpl1 extends Foo {
override def foo() {println("Impl")}
}
class FooImpl2 extends FooImpl1 with M