I am learning Scala and I cannot figure out how to translate the following Java code into Scala:
class Parent {
Parent(int i) {}
}
public class Test extends Parent {
final static int I = 1;
Test() {
super(I);
}
}
Please help me, thanks.
Here are my failed attempts:
1.
class Parent(val i: Int) {}
object Test {
val I = 1
}
class Test extends Parent(I) {
}
2.
class Parent(val i: Int) {}
class Test extends Parent(I) {
val I = 1
}
class Parent(i: Int)
class Test extends Parent(Test.I) // `super` is done in the parent's constructor
object Test {
val I = 1 // `static` members go in an `object`
}
Note:
You don't actually need the empty braces.
Only declare i with val if you want it to be publicly accessible (but not modifiable). It's private by default.
Related
I want to get the class name of the class pass-in into a generic class
class GernericClass<T> {
fun printOut() {
println(T::class.java.name) // I want something like this
}
}
This is my main function
fun main() {
val className = GernericClass<SomeObjectClass>()
className.printOut() // wanted output: SomeObjectClass
}
Is it possible to get the class name only by calling GernericClass<SomeObjectClass>()
Need a subclass to specify the type of T, because of generic erasureļ¼
fun main() {
val className = object:GernericClass<SomeObjectClass>(){}
className.printOut()
}
fun printOut() {
val clazz =
(this.javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0] as Class<*>
println(clazz) // I want something like this
}
Is it possible to have a trait be a singleton?
What I am trying to achieve is to have a clean and lightweight API I can extend throughout my application like the following:
trait SingletonTrait {
// element I wish to be unique throughout my application
val singletonElement = ///
...
}
// uses *singletonElement*
object MainApplication extends SingletonTrait {
...
}
// uses *singletonElement*
class SomeClass(...) extends SingletonTrait {
...
}
In the same idea implied by a getOrCreate() function that would retrieve an existing instance of an element if one already exists or creates it otherwise.
Maybe just create value in companion object and reference it in trait?
trait SingletonTrait {
final lazy val singletonElement = SingletonTrait.SingletonElement
}
object SingletonTrait {
lazy val SingletonElement = {
println("Creating singleton element!")
"singleton element"
}
}
// uses *singletonElement*
class SomeClass() extends SingletonTrait {
println(s"Using ${singletonElement} in class.")
}
new SomeClass()
new SomeClass()
new SomeClass()
It prints:
Creating singleton element!
Using singleton element in class.
Using singleton element in class.
Using singleton element in class.
Technically you could do this like so
object SingletonElement {
var count = 0
}
trait SingletonTrait {
final val singletonElement = SingletonElement
}
object MainApplication extends SingletonTrait {
singletonElement.count = singletonElement.count + 1
}
class SomeClass extends SingletonTrait {
singletonElement.count = singletonElement.count + 1
}
We can test that the same object is used like so
new SomeClass
MainApplication
SingletonElement.count
which should output
res2: Int = 2
which shows the same SingletonElement was used.
I am writing Play 2.5 application using Scala. I have following piece of code:
#ImplementedBy(classOf[BarRepositoryImpl])
trait BarRepository {
def bar = //some actions
}
class BarRepositoryImpl extends BarRepository
case class Foo( /*some fields*/) {
#Inject private var barRepository: BarRepository = null
def foo1 = {
val a = barRepository.bar //here barRepository is always null
// some actions with 'a' and returning some result which depends on 'a'
}
}
I also have a controller where I inject BarRepository as well, but through constructor and there everything works well while in the class Foo on the line val a = barRepository.bar I get a NullPointerException. Could someone help to figure out what's the problem? Is it forbidden to use injection in case class?
If you don't want to pollute your case class signature with Guice injected annotation and fields then simply add an implicit dependency on the method that needs it instead:
case class Foo( /*some fields*/) {
def bar1(someField: Int)(implicit barRepository: BarRepository) = {
// some code that interacts with barRepository
}
}
The calling class will have to have the BarRepository as an implicitly injected parameter. E.g. a Play controller like:
#Singleton
class HomeController #Inject()(cc: ControllerComponents)
(implicit barRepository: BarRepository)
extends AbstractController(cc) {
def index() = Action { implicit request =>
val foo = Foo("field")
val bar = foo.bar1
// ...
}
}
I would have assumed that you inject the object in your class signature?
case class Foo #Inject()(barRepository:BarRepository, /* your fields */){
/** some stuff **/
}
I wan't to build a class Animal which I can find the number of animals were created. In Scala there is no option to static variable, so how can I implement such functionality in Scala (I am looking for non-specific solution)?
Thanks!
For example in Java:
public class Amimal {
static int number_of_aminals = 0;
public Animal() {
number_of_animals++;
}
}
You can create a companion object for your case class which acts as a singleton:
case class Animal(name:String) {
Animal.incrementAnimal
}
object Animal {
def incrementAnimal = ...
}
However, be advised that following the approach above will require you to use mutable variables (variables defined by var instead of val) which is discouraged in Scala. So you may want to revisit your design to use immutable values.
One option would be:
import Animal
class Animal {
Animal.increment()
}
object Animal {
private[this] var _count = 0
def increment(): Unit = { _count += 1 }
def count: Int = _count
}
Though you might want to use AtomicInt.
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.