Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala: Specifying public method overriding protected method

I'm writing a trait that should specify the method clone returning a CloneResult, as so:

trait TraitWithClone extends Cloneable {
  def clone: CloneResult
}

The intention here is to tighten up the return type of java.lang.Object's clone() to something useful to this interface. However, when I try to compile this, I get:

error: overriding method clone in trait View2 of type ()CloneResult; method clone in class Object of type ()java.lang.Object has weaker access privileges; it should be public; (Note that method clone in trait View2 of type ()CloneResult is abstract, and is therefore overridden by concrete method clone in class Object of type ()java.lang.Object)

How can I require that an implementation be public, when Scala doesn't have the keyword? I know I can do:

trait TraitWithClone extends Cloneable {
  override def clone = cloneImpl
  protected def cloneImpl: CloneResult
}

...but that seems like a hack. Any suggestions?

like image 354
Kenneth Allen Avatar asked Dec 23 '11 17:12

Kenneth Allen


People also ask

Can we override protected method as public?

Yes, the protected method of a superclass can be overridden by a subclass. If the superclass method is protected, the subclass overridden method can have protected or public (but not default or private) which means the subclass overridden method can not have a weaker access specifier.

How does override work in Scala?

Scala overriding method provides your own implementation of it. When a class inherits from another, it may want to modify the definition for a method of the superclass or provide a new version of it. This is the concept of Scala method overriding and we use the 'override' modifier to implement this.

Can I override public method with private Java?

No, we cannot override private or static methods in Java.


1 Answers

Here's the important part of the error message: "and is therefore overridden by concrete method clone in class Object".

You should provide an implementation of the clone method in your trait. It's not ideal, but it's what you have to do since clone is a concrete method on Object.

trait TraitWithClone extends Cloneable {
  override def clone: CloneResult = throw new CloneNotSupportedException
}

Although, usually you just do this sort of thing in your concrete class directly:

class Foo extends Cloneable {
  override def clone: Foo = super.clone.asInstanceOf[Foo]
}

scala> new Foo
res0: Foo = Foo@28cc5c6c

scala> res2.clone
res1: Foo = Foo@7ca9bd
like image 73
leedm777 Avatar answered Nov 12 '22 01:11

leedm777