In Scala Language Spec. I found that
A different form of qualification is protected[this]. A member M marked with this modifier is called object-protected; it can be accessed only from within the object in which it is defined. That is, a selection p.M is only legal if the prefix is this or O.this, for some class O enclosing the reference. In addition, the restrictions for unqualified protected apply.
However I understand the case with this
e.g
this.protectedMember
But what I didn't get is
O.this, for some class O enclosing the reference .
please Help..
However as my understanding says that this is something that is realted with inner class as we do in Swing to get the outer class object eg
OuterClass.this.someMethod in anonymous inner class.
The expression C.this is legal in the statement part of an enclosing class or object definition with simple name C. It stands for the object being defined by the innermost such definition.
E.g. you can have
class O {
class I {
// O.this is the instance of O this I instance is nested in
def M = ...
M // calls M in I
O.this.M // calls M in O
}
protected[this] def M = ...
}
Related
I have written the following code:
class a {
object c {
var a = "STATIC"
def m() = print("STATIC METHOD")
var f = () => print("STATIC FUNCTION")
}
}
object m {
def main(args: Array[String]) = {
var o = new a()
o.c.m()
}
}
Can I say that the variables, functions and methods that are declared in object c can be static?
If I change name of object c with a then will the object becomes a companion object?
Scala has no true meaning of 'static' that Java does.
The fact that objects have a backing on the JVM that uses static methods / fields is a leaking implementation detail that you only need to deal with if using Java/JVM interop.
Unless you explicitly need that interop, you need to stop thinking of declared objects as 'static' and instead think of them as singletons within their given scope.
An inner object nested under a class, means that there is only ever going to be 1 instance of that object, for each class instance, unlike inner classes which could have multiple instances.
This applies at the top level as well, except that Scala can do additional compatibility with other JVM languages, and mark some of the methods/members as static.
Fields and methods in an object are how Scala declares things that you would have used static for in Java. I guess you can, for intuition sake, say that those fields are usually static (as in only one of those in a JVM at once).
However, in your example, you put an object inside a class, making it no longer static. You can easily check this with a few lines of code (that you can find here on Scastie).
class MyClass {
object Embedded {
val a = "field"
def m = println("method")
}
}
val a = new MyClass().Embedded
val b = new MyClass().Embedded
// prints "a and b are different objects"
if (a eq b)
println("a and b are the same object")
else
println("a and b are different objects")
Regarding your second question: no, class and object must be in the same scope in order for it to be a companion object. You can find more details on the Scala Language Specification.
I quote from there:
Generally, a companion module of a class is an object which has the same name as the class and is defined in the same scope and compilation unit. Conversely, the class is called the companion class of the module.
To answer you questions:
The methods and fields in a.c are not globally static because they need an instance of a to exist. If a were an object, a.c would be static too.
If you want to have a companion object with static fields and methods for your class a it has to be defined outside of a's code block, like this:
class a {
/* non-static stuff goes here */
}
object a {
/* static stuff goes there */
def m() = print("STATIC METHOD")
}
You must keep both in the same file, defining the object or the
class first doesn't matter, so it generally depend on a convention or what makes most sense depending on use case.
If you want to call the static method a.m inside the class a, you will still need to call it a.m and not just m. But the class a will be able to use private fields and methods of object a, because they are companions.
As others already said, static doesn't really exist in Scala, but the concept transpires from Java since Scala is in most cases compiled into java bytecode.
Last advice, the convention is usually the same in Scala and in Java for classes and object: the first-letter of their name should be uppercase (except in some advanced Scala cases)
Before Scala 2.10 I had
class A {
class B(b: Int) {
}
}
and somewhere in code recreate class B with
val bCtor = bInstance.getClass.getConstructor(classOf[Int])
bCtor.newInstance ...
and everything was fine. It was with signature public A$B(Int)
Now constructor have 2!!! arguments. It has a new signature public A$B(A,Int). What is argument with type A? I don't have access to A class from my function. It there any workaround?
For example newInstance with arguments - It doesn't work anymore for inner class
Be carful not to confuse java inner class with scala path-dependent type
(from the Programming In ScalaBook) :
A path-dependent type resembles the syntax for an inner class type in Java, but there is a crucial difference: a path-dependent type names an outer object, whereas an inner class type names an outer class
So in your case bInstance is related to an aInstance.
My assumption is that aInstance is the object passed as the first parameter to this constructor.
You can use an unconstrained self-type annotation to have a way to refer to the A's version of this even from within B (where this now refers to the B instance).
package rrs.scribble
object OuterInner {
class Outer { oThis =>
class Inner {
def identify { printf("I am %s; I'm inside of %s%n", this, oThis) }
}
val inner = new Inner
}
def oiTest {
val o1 = new Outer
o1.inner.identify
}
}
In the REPL:
Welcome to Scala version 2.10.0 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_37).
scala> import rrs.scribble.OuterInner._
import rrs.scribble.OuterInner._
scala> oiTest
I am rrs.scribble.OuterInner$Outer$Inner#63d0d313; I'm inside of rrs.scribble.OuterInner$Outer#22d1b797
First, adding A as the first constructor argument is also the way it works in Java:
If this Class object represents an inner class declared in a non-static context, the formal parameter types include the explicit enclosing instance as the first parameter.
Second,
What is argument with type A? I don't have access to A class from my function.
If you have a B (as seems from your example), then you can access its enclosing instance (it doesn't seem to be documented officially, and so may change in the future versions of Java):
val aInstance = bInstance.getClass.getDeclaredField("this$0").get(bInstance)
bCtor.newInstance(aInstance, ...)
If you don't, then you can't create a B (without an A), but you shouldn't be able to. What would you expect this code to return?
class A(foo: Int) {
class B {
def bar = foo
}
}
classOf[A#B].getConstructor().newInstance().bar
#evantill is right, the only constructor of B is A$B.<init>(A, Int). So bInstance.getClass.getConstructor(classOf[A], classOf[Int]) works.
I just ran into a difficulty while learning Scala. I have an inheritance hierarchy that is essentially equivalent to this:
class A {
protected def myMethod() = println("myMethod() from A")
}
class B extends A {
def invokeMyMethod(a: A) = a.myMethod()
}
But trying to compile this sample, I get the error "test.scala:7: error: method myMethod cannot be accessed in A".
Coming from Java, my understanding is that protected members should be accessible at any point from a derived class, and nowhere have I seen anything that tells me that protected members in Scala are limited by instance. Does anyone have an explanation for this?
Quoting the Scala Language Specification:
A protected identifier x may be used as a member name in a selection r .x
only if one of the following applies:
– The access is within the template defining the member, or, if a qualification C is given, inside the package C, or the class C, or its companion module, or
– r is one of the reserved words this and super, or
– r ’s type conforms to a type-instance of the class which contains the access.
These three rules define when exactly an instance is allowed to access another instance's protected members. One thing that's interesting to note is that, by the last rule, when B extends A, an instance of A may access protected members of a different instance of B... but an instance of B may not access protected members of another A! In other words:
class A {
protected val aMember = "a"
def accessBMember(b: B) = b.bMember // legal!
}
class B extends A {
protected val bMember = "b"
def accessAMember(a: A) = a.aMember // illegal!
}
Please look at the following code.
trait MyTrait { val myVal : String }
class MyClass extends MyTrait { val myVal = "Value" }
class MyClass2(val myVal: String) extends MyTrait
Why does the initialization order differ in case of MyClass and MyClass2?
The constructor of MyClass will be as
MyClass() {
MyTrait$class.$init$(this);
myVal = value
}
The constructor of MyClass2 will be
MyClass2(String myVal) { this.myVal = myVal; MyTrait$class.$init$(this) }
I think the initialization order should be as MyClass2's constructor does, the same for both cases.
At the end of section 5.1 of the Scala specification, the following is defined:
Template Evaluation. Consider a template sc with mt 1 with mt
n {stats}. If this is the template of
a trait (§5.3.3) then its
mixin-evaluation consists of an eval-
uation of the statement sequence
stats. If this is not a template of a
trait, then its evaluation consists of
the following steps.
First, the superclass constructor sc is evaluated (§5.1.1).
Then, all base classes in the template’s linearization (§5.1.2) up
to the template’s superclass denoted
by sc are mixin-evaluated.
Mixin-evaluation hap- pens in reverse
order of occurrence in the
linearization.
Finally the statement sequence stats is evaluated.
Note, however, that the constructor parameters may be used by any constructors that follow it. Therefore, it needs to be initialized before them. This is made explicit at the end of section 5.1.1:
An evaluation of a constructor
invocation x.c targs. .
.(argsn) consists of the following
steps:
First, the prefix x is evaluated.
Then, the arguments args1 , . . . , argsn are evaluated from left to
right.
Finally, the class being constructed is initialized by evaluating the
template of the class referred to by
c.
This you don't have any problem with, but you do have a problem with {stats} being executed last. The reason why {stats} is executed last is that it may reference attributes of its ancestor classes and traits, whereas the ancestors obviously have no knowledge about its descendants. Therefore, the ancestors need to be fully initialized before {stats} gets executed.
Of course, it is possible that you do need early initialization. This is covered by section 5.1.6: Early Definitions. Here's how you'd write it:
class MyClass extends { val myVal = "Value" } with MyTrait
I'm just going over some Scala tutorials on the Internet and have noticed in some examples an object is declared at the start of the example.
What is the difference between class and object in Scala?
tl;dr
class C defines a class, just as in Java or C++.
object O creates a singleton object O as instance of some anonymous class; it can be used to hold static members that are not associated with instances of some class.
object O extends T makes the object O an instance of trait T; you can then pass O anywhere, a T is expected.
if there is a class C, then object C is the companion object of class C; note that the companion object is not automatically an instance of C.
Also see Scala documentation for object and class.
object as host of static members
Most often, you need an object to hold methods and values/variables that shall be available without having to first instantiate an instance of some class.
This use is closely related to static members in Java.
object A {
def twice(i: Int): Int = 2*i
}
You can then call above method using A.twice(2).
If twice were a member of some class A, then you would need to make an instance first:
class A() {
def twice(i: Int): Int = 2 * i
}
val a = new A()
a.twice(2)
You can see how redundant this is, as twice does not require any instance-specific data.
object as a special named instance
You can also use the object itself as some special instance of a class or trait.
When you do this, your object needs to extend some trait in order to become an instance of a subclass of it.
Consider the following code:
object A extends B with C {
...
}
This declaration first declares an anonymous (inaccessible) class that extends both B and C, and instantiates a single instance of this class named A.
This means A can be passed to functions expecting objects of type B or C, or B with C.
Additional Features of object
There also exist some special features of objects in Scala.
I recommend to read the official documentation.
def apply(...) enables the usual method name-less syntax of A(...)
def unapply(...) allows to create custom pattern matching extractors
if accompanying a class of the same name, the object assumes a special role when resolving implicit parameters
A class is a definition, a description. It defines a type in terms of methods and composition of other types.
An object is a singleton -- an instance of a class which is guaranteed to be unique. For every object in the code, an anonymous class is created, which inherits from whatever classes you declared object to implement. This class cannot be seen from Scala source code -- though you can get at it through reflection.
There is a relationship between object and class. An object is said to be the companion-object of a class if they share the same name. When this happens, each has access to methods of private visibility in the other. These methods are not automatically imported, though. You either have to import them explicitly, or prefix them with the class/object name.
For example:
class X {
// class X can see private members of object X
// Prefix to call
def m(x: Int) = X.f(x)
// Import and use
import X._
def n(x: Int) = f(x)
private def o = 2
}
object X {
private def f(x: Int) = x * x
// object X can see private members of class X
def g(x: X) = {
import x._
x.o * o // fully specified and imported
}
}
An object has exactly one instance (you can not call new MyObject). You can have multiple instances of a class.
Object serves the same (and some additional) purposes as the static methods and fields in Java.
As has been explained by many, object defines a singleton instance. The one thing in the answers here that I believe is left out is that object serves several purposes.
It can be the companion object to a class/trait, containing what might be considered static methods or convenience methods.
It can act much like a module, containing related/subsidiary types and definitions, etc.
It can implement an interface by extending a class or one or more traits.
It can represent a case of a sealed trait that contains no data. In this respect, it's often considered more correct than a case class with no parameters. The special case of a sealed trait with only case object implementors is more or less the Scala version of an enum.
It can act as evidence for implicit-driven logic.
It introduces a singleton type.
It's a very powerful and general construct. What can be very confusing to Scala beginners is that the same construct can have vastly different uses. And an object can serve many of these different uses all at once, which can be even more confusing.
Defining an object in Scala is like defining a class in Java that has only static methods. However, in Scala an object can extend another superclass, implement interfaces, and be passed around as though it were an instance of a class. (So it's like the static methods on a class but better).
The formal difference -
you can not provide constructor parameters for Objects
Object is not a type - you may not create an instance with new operator. But it can have fields, methods, extend a superclass and mix in traits.
The difference in usage:
Scala doesn't have static methods or fields. Instead you should use object. You can use it with or without related class. In 1st case it's called a companion object. You have to:
use the same name for both class and object
put them in the same source file.
To create a program you should use main method in object, not in class.
object Hello {
def main(args: Array[String]) {
println("Hello, World!")
}
}
You also may use it as you use singleton object in java.
In scala, there is no static concept. So scala creates a singleton object to provide entry point for your program execution.
If you don't create singleton object, your code will compile successfully but will not produce any output. Methods declared inside Singleton Object are accessible globally. A singleton object can extend classes and traits.
Scala Singleton Object Example
object Singleton{
def main(args:Array[String]){
SingletonObject.hello() // No need to create object.
}
}
object SingletonObject{
def hello(){
println("Hello, This is Singleton Object")
}
}
Output:
Hello, This is Singleton Object
In scala, when you have a class with same name as singleton object, it is called companion class and the singleton object is called companion object.
The companion class and its companion object both must be defined in the same source file.
Scala Companion Object Example
class ComapanionClass{
def hello(){
println("Hello, this is Companion Class.")
}
}
object CompanoinObject{
def main(args:Array[String]){
new ComapanionClass().hello()
println("And this is Companion Object.")
}
}
Output:
Hello, this is Companion Class.
And this is Companion Object.
In scala, a class can contain:
1. Data member
2. Member method
3. Constructor Block
4. Nested class
5. Super class information etc.
You must initialize all instance variables in the class. There is no default scope. If you don't specify access scope, it is public. There must be an object in which main method is defined. It provides starting point for your program. Here, we have created an example of class.
Scala Sample Example of Class
class Student{
var id:Int = 0; // All fields must be initialized
var name:String = null;
}
object MainObject{
def main(args:Array[String]){
var s = new Student() // Creating an object
println(s.id+" "+s.name);
}
}
I am sorry, I am too late but I hope it will help you.
The object keyword creates a new singleton type, which is like a class that only has a single named instance. If you’re familiar with Java, declaring an object in Scala is a lot like creating a new instance of an anonymous class.
Scala has no equivalent to Java’s static keyword, and an object is often used in Scala where you might use a class with static members in Java.
Object is a class but it already has(is) an instance, so you can not call new ObjectName. On the other hand, Class is just type and it can be an instance by calling new ClassName().
A class is just like any other class in other languages. You define class just like any other language with some syntax difference.
class Person(val name: String)
val me = new Person("My name")
However, object is a class with single object only. This makes it interesting as it can be used to create static members of a class using companion object. This companion object has access to private members of the class definition and it has the same name as the class you're defining.
class Person(var name: String) {
import Person._
def hi(): String = sayHello(name)
}
object Person {
private def sayHello(name: String): String = "Hello " + name
}
val me = new Person("My name")
me.hi()
Also, noteworthy point is that object class is lazily created which is another important point. So, these are not instantiated unless they are needed in our code.
If you're defining connection creation for JDBC, you can create them inside object to avoid duplication just like we do in Java with singleton objects.
Scala class same as Java Class but scala not gives you any entry method in class, like main method in java. The main method associated with object keyword. You can think of the object keyword as creating a singleton object of a class that is defined implicitly.
more information check this article
class and object keyword in scala programming
The object is similar to the static class in Java to some extend, the static characteristic means the static class need not to create an object when putting to the JVM, it can be used by it's class name directly and the same instance(same data state) is shared wherever it is used.
If you are coming from java background the concept of class in scala is kind of similar to Java, but class in scala cant contain static members.
Objects in scala are singleton type you call methods inside it using object name, in scala object is a keyword and in java object is a instance of class