Scala: statically access class object of another class - class

I have two classes "ClassA" and "ClassB". I want to get the class object from the ClassA * and apparently I cannot do it.
class ClassA {
ClassB.getClass() // <-- won't compile
}
class ClassB {
}
The only way would be to instantiate the specific class and call the getClass() from the newly created object. But I really don't want to create a new object for this!
class ClassA {
new ClassB().getClass() // <-- compiles, but I don't want to create a new object!
}
class ClassB {
}
In Java this is straight forward. What's the problem with Scala doing the same?
*For context, I ultimately would like to obtain the FQCN of ClassB.

classOf[ClassB] will give you the Class object of ClassB.

Here is working example:
class ClassA {
val bClass = classOf[ClassB]
}
class ClassB {
}
object Main {
def main(args: Array[String]): Unit = {
println(new ClassA().bClass/*<- here you got java.lang.Class object*/.getName())
}
}
Scala 2.11.1 compiles ClassA to:
#ScalaSignature(bytes="...")
public class ClassA {
private final Class<ClassB> bClass = ClassB.class;
public Class<ClassB> bClass() { return this.bClass; }
}

Related

Scala test object class matcher with inheritance

I would like to write a Scala test which checks the exact class of an object created with factory method.
class Base { }
class Derived extends Base { }
class TestSpec {
test("test instance class") {
val result = new Derived()
// I want to check that result is exactly Derived type
result should be a[Derived]
result should not be a[Base]
}
}
I'm looking for something to test if object returned from my factory method for specific parameters is always base class. So it would be something like this is C#:
public class Base { }
public class Derived : Base { }
public class Program
{
public static void Main(string[] args)
{
var baseObject = new Base();
var derivedObject = new Derived();
var baseResult = baseObject.GetType().IsSubclassOf(typeof(Base));
var derivedResult = derivedObject.GetType().IsSubclassOf(typeof(Base));
Console.WriteLine(string.Format("Base is subclass of Base: {0}\nDerived is subclass of Base: {1}", baseResult, derivedResult));
}
}
you can do this :
class A{}
class B extends A{}
val result = new B()
result.getClass.getName shouldEqual classOf[B].getName
result.getClass.getName.equals(classOf[A].getName) shouldBe false
new Derived() will always be an instance of Base as it inherits from Base, which means:
new Derived().isInstanceOf[Base]
will return true.
But the opposite is false: Base won't be an instance of Derived.
Thus, to check if it's the Base class (and not the Derived class), you can use these two combined conditions:
new Base() should not be a[Derived]
new Base() shouldBe a[Base]
and to check if it's the Derived class, the following is enough:
new Derived() shouldBe a[Derived]

Reuse a case class inside an object in scala

I have an object that contains one or more case classes and associated methods. I would like to reuse this case class within another object (which has similar characteristics as this object but also some differentiating methods).
private object abc {
/* ... */
case class xyz(..) { def someFunc(){} }
object xyz { def apply() {} }
}
private object extendabc {
// How to reuse case class xyz here?
}
If you want to just access you can use this kind of a code .
private object abc {
case class xyz() {
def someFunc(){}
}
object xyz { }
}
private object extendabc {
val a = new abc.xyz()
a.someFunc()
}
You need to call this way because xyz is a nested member of the object abc .
Look here.
Also please note you cannot define a apply method in the companion object of a case class as it provides the exact same apply() method (with the same signature.

Use #ClassRule in Kotlin

In JUnit you can use #ClassRule to annotate an static field.
How can I do this in Kotlin?
I tried:
object companion {
#ClassRule #JvmStatic
val managedMongoDb = ...
}
and
object companion {
#ClassRule #JvmField
val managedMongoDb = ...
}
but none of the last works because rule isn't executed.
I double checked that exactly same rule works fine without static context:
#Rule #JvmField
val managedMongoDb = ...
You are not using companion objects correctly. You are declaring an object (single instance of a class) called companion instead of creating a companion object inside of a class. And therefore the static fields are not created correctly.
class TestClass {
companion object { ... }
}
Is very different than:
class TestClass {
object companion { ... } // this is an object declaration, not a companion object
}
Although both are valid code.
Here is a correct working example of using #ClassRule, tested in Kotlin 1.0.0:
class TestWithRule {
companion object {
#ClassRule #JvmField
val resource: ExternalResource = object : ExternalResource() {
override fun before() {
println("ClassRule Before")
}
override fun after() {
println("ClassRule After")
}
}
}
#Test fun testSomething() {
println("Testing...")
}
}
This outputs:
ClassRule Before
Testing...
ClassRule After

Why can't I access my objects member variable?

I have the following class setup:
class MyClass {
class MyInnerClass(memberVar: String)
def getAInner: MyInnerClass = {
new MyInnerClass("hello")
}
}
Then I have the following code outside of the class:
def myFunction = {
val a = new MyClass
val b = a.getAInner.memberVar // value memberVar is not a member of a.MyInnerClass
}
Why is this?
You need to add the keyword val to make memberVar public otherwise it's a private value:
class MyClass {
class MyInnerClass(val memberVar: String)
def getAInner: MyInnerClass = {
new MyInnerClass("hello")
}
}
#Noah's answer is totally correct, but I would also throw out the option of using case class. See here for some of the sugar it provides. I use it almost reflexively. In your example, it would be:
object MyClass {
case class MyInnerClass(memberVar: String)
def getAInner: MyInnerClass = {
new MyInnerClass("hello")
}
}
def myFunction = {
val b = MyClass.getAInner.memberVar
}
I tend to do it this way because invariably, I want to take advantage of the sane defaults case class provides.
I also chose to use object for the outer type, because it doesn't have any parameters, although you may have just done that for simplicity's sake.

Scala abstract class method that returns a new corresponding class child object

I have the following class in my mind:
abstract class MyClass (data: MyData) {
def update(): MyClass = {
new MyClass(process())
}
def process(): MyData = {
...
}
}
However, abstract classes cannot be instantiated so the line new MyClass(process()) is an error. My question is - is there any way to tell the compiler that in case of each of the child classes of MyClass I want to create an object of exactly that child class? It seems an overkill to write this method awhole in all child classes. Playing with type parameters of the class or method I could not acheive that myself.
How about something like this? MyClass is parametrized with the concrete type. Of course, all concrete classes have to implement a method that actually returns a new instance of Self.
trait MyClass[+Self <: MyClass[Self]] {
def update(): Self = {
makeNew(process())
}
def process(): MyData = {
// ...
}
protected def makeNew(data: MyData): Self
}
class Concrete0 extends MyClass[Concrete0] {
protected def makeNew(data: MyData) = new Concrete0
}
class RefinedConcrete0 extends Concrete0 with MyClass[RefinedConcrete0] {
override protected def makeNew(data: MyData) = new RefinedConcrete0
}
Credit: IttayD’s second update to his answer to this question.
To completly avoid implementing almost identical method in all subclasses you would need to use reflection. I guess that would be your last resort if you have chosen Scala.
So here is how to minimize the repetitive code:
// additional parameter: a factory function
abstract class MyClass(data: MyData, makeNew: MyData => MyClass) {
def update(): MyClass = {
makeNew(process())
}
def process(): MyData = {
...
}
}
class Concrete(data: MyData) extends MyClass(data, new Concrete(_))
This way you repeat only the shortest fragment required to instantiate the subclass.