Make constructor parameters public in subclass - scala

I want the protected fields of a class to be made publicly visible in a subclass:
class MyClass(protected val someDao: SomeDao)
class TestMyClass extends MyClass(mock[SomeDao])
Now I want to access someDao like so:
val testClass = new TestMyClass
testClass.someDao
I've read that in Java and Scala access modifiers can be broadened but not restricted in subclasses (although these are just constructor parameters, not private fields per se). How can I achieve that in this example?
EDIT:
The answers provided suggest making someDao public in the base class. This is not what I want. I want it to remain private, but just change its visibility to public in the TestMyClass class.

As far as I know, an overriden val cannot access the super implementation.
If you can modify the base class, one solution is to explicitely define an accessor method, which can be overriden; something like this:
class MyClass(_someDao: SomeDao) {
protected def someDao = _someDao
}
class TestMyClass extends MyClass(mock[SomeDao]) {
override def someDao = super.someDao
}
If you cannot change the base class, one workaround would be to define a public accessor method with a different name:
class MyClass(protected val someDao: SomeDao)
class TestMyClass extends MyClass(mock[SomeDao]) {
def someDao2 = someDao
}

Add var or val to parameters declaration:
class MyClass(val someDao: SomeDao)
In this case only getter function will be generate for someDao field. So when you write testClass.someDao you retrieve not the someDao as field you use their getter function.
Good example about visibility of class parameters in Scala demostrated at this article.
Regarding to your last updates
Set package scope for parameter declaration:
class MyClass(private[lastPackageOfSomeDao] val someDao: SomeDao)

Related

Access modifier location explanation in scala

I discovered that we can use access modifier before class as well as after class name. For example, I have 2 classes as follows
package com.company.package.sub_package
protected class Animal1{
def makeSound(): Unit = println("Bow ow")
}
object Animal1{
def main(args: Array[String])
{
val animal = new Animal2()
animal.makeSound()
}
}
package com.company.package.sub_package
class Animal2 protected{
def makeSound(): Unit = println("Meow")
}
object Animal2{
def main(args: Array[String])
{
val animal = new Animal1()
animal.makeSound()
}
}
Here an error shows up in Animal1 main method saying Animal2 cannot be accessed in object Animal1.
If I extend Animal2 class, the sub class is able to access the parent class.
What I understand from this is if we write protected after the class name, it is not available to classes in same package and if I right it before class, it is available to all classes in the package, only to its sub classes, is this a correct assumption? What is the exact significance of location of an access modifier?
What is the exact significance of location of an access modifier?
The access modifier always comes before the thing whose access it modifies.
In your first example, protected comes before the class Animal1, so it regulates access to the class.
In your second example, protected comes before the primary constructor, so it regulates access to the primary constructor. (Note: it's not obvious that it comes before the primary constructor because Animal2 has an empty primary constructor, but the Scala Language Specification says that if there is no parameter list for a class, an empty () parameter list is inserted.)
So, your Animal2 class is actually equivalent to
class Animal2 protected () {
def makeSound(): Unit = println("Meow")
}
A typical reason for restricting access to the primary constructor is to control instance creation either through auxiliary constructors or factory methods in the companion module.
You can find the specification for access modifiers of the primary constructor in section 5.3 Class Definitions of the Scala Language Specification.
The access modified before a class is like the access modifier for any other value in a class. It specifies the visibility of that class outside the containing class and in subclasses.
The access modifier after the class applies to the constructor and specifies the visibility of the constructor outside the companion object for that class
Typically it is used to hide the default constructor:
class Positive private(val i: Int)
object Positive {
def apply(i: Int): Positive = new Positive(math.abs(i))
}
You can access the i field of a Positive but it can never be negative.

Scala: Extend base class that contains 'apply' method

I have a base class in the 'common' module that looks like this:
class BaseClass(args: Seq[String] = Seq()) extends Serializable {
private val argMap: Map[String, String] =
// <More code here...>
object BaseClass {
def apply(args: Seq[String] = Seq()): BaseClass = new BaseClass(args)
}
Now I want to extend this BaseClass in my 'module' so I am trying this...
class MyNewClass(args: Seq[String] = Seq()) extends com.xyz.BaseClass {
// Add additional code here
}
object MyNewClass extends com.xyz.BaseClass {
def apply(args: Seq[String] = Seq()): MyNewClass = new com.xyz.MyNewClass(args)
}
My understanding is, when I instantiate MyNewClass it will automatically instantiate & call the 'apply' method of the base class but that's not happening. What is a proper way to extend the BaseClass in a way that all its variables & methods can be accessed via the Child class?
My understanding is, when I instantiate MyNewClass it will automatically instantiate & call the 'apply' method of the base class...
Your understanding isn't quite on.
extends com.xyz.BaseClass means that this class inherits from the base class, not the singleton object.
And new com.xyz.MyNewClass(args) creates a new instance of the specified class, bypassing the apply() method in any companion object.
What is a proper way to extend the BaseClass in a way that all its variables & methods can be accessed via the Child class?
The current code does exactly that. MyNewClass, and its companion object, inherits all members from BaseClass. Nothing is inherited from the BaseClass companion object because you can't extend an object, and you don't inherit the access permissions from BasseClass so while a BaseClass instance can access private members of the BaseClass companion object, a MyNewClass instance cannot.

Scala traits exposing protected members?

Given a class like:
class MyClass {
protected object MyObj { ... }
}
is it possible to write a trait that will permit exposing MyObj. E.g. with inheritance I could do the following:
class TestMyClass extends MyClass {
val getMyObj = MyObj
}
but I want to do this via a trait, something like the following which doesn't typecheck:
trait ExposeMyObj {
val getMyObj = MyObj // super.MyObj/this.MyObj don't work
}
and use it like:
class TestMyClass extends ExposeMyObj
Is it possible to reproduce the functionality in TestMyClass into a trait to expose the protected object, and if so how?
If you know that your trait will always be mixed in to an instance of MyClass (or a subclass), you can enforce the expectation with a self-type, and then access the object:
trait ExposeMyObj {
self: MyClass =>
val getMyObj = MyObj
}
Edit: an example of using this trait:
class TestMyClass extends MyClass with ExposeMyObj
val test = new TestMyClass
test.getMyObj // accesses MyObj defined in MyClass.
Edit 2: attempting to address #jbrown's comment (re: testing queries within repos) - I would look at doing something like the following - first, in each repo's file, add a trait for each repo holding the queries for that repo:
trait UserQueries { // you could look at making this protected, if you like
protected def query1(param: String) = List(param) // very silly implementation, but hopefully enough to make the point
... // other queries
}
class UserRepo extends UserQueries // Has (internal) access to those queries
Then in the test class file for a given repo:
class UserQueriesTester extends UserQueries with ScalaTest { // or whatever test framework you are using
// (public) tests to run - eg:
def testQuery1 = query1("test") should be (List("test"))
}

How does one "override" an inner class in Scala?

In the Scaladoc of class Enumeration#Val, I can read: "A class implementing the Value type. This class can be overridden to change the enumeration's naming and integer identification behaviour." I am puzzled: how do I override a class? Things like override class Val extends super.Val are not permitted.
There are no virtual classes in Scala (yet), so you can't write override class Val ..., and then be sure that invoking new Val will dynamically choose the right class for the new instance. What would happen instead is that the class would be chosen based on the type of the reference to the instance of the enclosing class (in this case, Enumeration).
The general trick to emulate virtual classes is to write class Val extends super.Val, and then override a protected method which serves as a factory for instances of the class. In this case, you would also have to override the method:
protected def Value(i: Int, name: String): Value = new Val(i, name)
Enumeration will create instances of Val only using this factory method. In general, this pattern requires discipline on the programmer's part, but can be ensured by declaring the constructors private, forcing the programmer to use the factory method.

Private and protected constructor in Scala

I've been curious about the impact of not having an explicit primary constructor in Scala, just the contents of the class body.
In particular, I suspect that the private or protected constructor pattern, that is, controlling construction through the companion object or another class or object's methods might not have an obvious implementation.
Am I wrong? If so, how is it done?
You can declare the default constructor as private/protected by inserting the appropriate keyword between the class name and the parameter list, like this:
class Foo private () {
/* class body goes here... */
}
Aleksander's answer is correct, but Programming in Scala offers an additional alternative:
sealed trait Foo {
// interface
}
object Foo {
def apply(...): Foo = // public constructor
private class FooImpl(...) extends Foo { ... } // real class
}