companion object to a private class: why isn't it valid? - scala

i needed two instances that has access to each other privates. i naturaly thought of a companion object that grants access to a one and only instance of it's companion class. the class itself i made private, so users cannot just create instances using new.
object A {
def apply = dual
lazy val dual = new A
}
private class A {
//some irrelevant logic...
}
this code does not compile. i get: class A escapes its defining scope as part of type A error, which i don't really understand. my current workaround was to define a trait with every method declaration the class should have and make class A extend that trait, while dual is of the trait type, and not class A type.
what's the theoretic problem i'm missing here? why is this forbiden?

Paolo's solution is good (+1), but he didn't explain the error message, so let me try that. The problem stems from the fact that every method needs a return type. Your original definition of apply and dual returned an object of class A, thus the implicit return type of both was A. That implies that A must be visible to clients - how else could they call the function or access the val? Moreover, as both - and their parent object too - are public, they are globally visible. However, you declared A private which means it must not be visible outside its package. So there is a conflict which can't be resolved by the compiler.
The general rule is that all parameter and return type of functions / members must have (at least) the same scope of visibility as the referring member itself*. Thus one trivial way to solve this problem would be to reduce the visibility of apply and dual to private. This would satisfy the compiler, but not you :-)
Your solution gets around the problem by changing the static return type to a public trait, which thus has the same visibility as the members referring to it. The dynamic type of the returned object is still class A, however, this need not be visible to clients. This is a classic example of the principle "program to interfaces, not implementations".
Note that to apply this principle to the full extent, one could turn class A into a private inner class of object A, thus making it innaccessible even for other classes within the same package:
trait A {
//...
}
object A {
def apply: A = dual
lazy val dual: A = new AImpl
private class AImpl extends A {
//some irrelevant logic...
}
}
* To be pedantic, the enclosing class / object may reduce the visibility of its members, like here:
private class Holder {
def member = new Hidden
}
private class Hidden
where member is public but its enclosing class is private, effectively hiding its members from the external world. So the compiler emits no complaints here.

I think you don't want a private class, but a class with a private constructor.
class A private()
object A {
def apply = dual
lazy val dual = new A
}
Now your class is "visible" to outside code, but only your companion object can create instances of it.

Related

Singleton Object vs Companion Object in Class

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)

How to explain the following sentences about private[this] and variance?

In Chapter 19 ,"Programming in scala 2nd edition",how to explain the bold sentences ?
object private members can be accessed only from within the object in
which they are defined. It turns out that accesses to variables from
the same object in which they are defined do not cause problems with
variance. The intuitive explanation is that, in order to construct a
case where variance would lead to type errors, you need to have a
reference to a containing object that has a statically weaker type
than the type the object was defined with. For accesses to object
private values, however,this is impossible.
I think the most intuitive way to explain what Martin is trying to say is to look at arrays in Java. Arrays in Java are covariant but don't type check according to covariance rules. This means they explode at runtime instead of compile time:
abstract class Animal {}
class Girafee extends Animal {}
class Lion extends Animal {}
public class Foo {
public static void main(String[] args) {
Animal[] animals = new Girafee[10];
animals[0] = new Lion();
}
}
The fact that I can do this is because:
Java doesn't restrict this at compile time (due to a design decision)
I have a reference to the underlying array which allows me to manipulate it's internal values
This doesn't hold when talking about private fields of a class from the outside.
For example, assume the following class:
class Holder[+T](initialValue: Option[T]) {
private[this] var value: Option[T] = initialValue
}
When creating an instance of Holder, I am not visible to it's internal fields, thus I cannot manipulate them directly like I did with the Java array. This way, the compiler makes sure they are protected, and each manipulation to the field will have to be through a method, where the type checker is strict and doesn't allow funky business.

Object extends Trait, Class extends Trait, both have to implement method

I have the following setup:
trait A
{
def doSomething(): Unit;
}
object B extends A
{
override def doSomething(): Unit =
{
// Implementation
}
}
class B(creator: String) extends A
{
override def doSomething(): Unit =
{
B.doSomething() // Now this is just completely unnecessary, but the compiler of course insists upon implementing the method
}
}
Now you may wonder why I even do this, why I let the class extend the trait as well.
The problem is, that somewhere in the Program there is a Collection of A.
So somewhere:
private val aList: ListBuffer[A] = new ListBuffer[A]
and in there, I also have to put Bs (among other derivates, namely C and D)
So I can't just let the B-class not extend it.
As the implementation is the same for all instances, I want to use an Object.
But there is also a reason I really need this Object. Because there is a class:
abstract class Worker
{
def getAType(): A
def do(): Unit =
{
getAType().doSomething()
}
}
class WorkerA
{
def getAType(): A =
{
return B
}
}
Here the singleton/object of B gets returned. This is needed for the implementation of do() in the Worker.
To summarize:
The object B is needed because of the generic implementation in do() (Worker-Class) and also because doSomething() never changes.
The class B is needed because in the collection of the BaseType A there are different instances of B with different authors.
As both the object and the class have to implement the trait for above reasons I'm in kind of a dilemma here. I couldn't find a satisfying solution that looks neater.
So, my question is (It turns out as a non-native-speaker I should've clarified this more)
Is there any way to let a class extend a trait (or class) and say that any abstract-method implementation should be looked up in the object instead of the class, so that I must only implement "doSomething()" (from the trait) once (in the object)? As I said, the trait fulfills two different tasks here.
One being a BaseType so that the collection can get instances of the class. The other being a contract to ensure the doSomething()-method is there in every object.
So the Object B needs to extend the trait, because a trait is like a Java interface and every (!) Object B (or C, or D) needs to have that method. (So the only option I see -> define an interface/trait and make sure the method is there)
edit: In case anyone wonders. How I really solved the problem: I implemented two traits.
Now for one class (where I need it) I extend both and for the other I only extend one. So I actually never have to implement any method that is not absolutely necessary :)
As I wrote in the comment section, it's really unclear to me what you're asking.
However, looking at your code examples, it seems to me that trait A isn't really required.
You can use the types that already come with the Scala SDK:
object B extends (()=>Unit) {
def apply() { /* implementation */ }
}
Or, as a variant:
object B {
val aType:()=>Unit = {() => /* implementation */ }
}
In the first case, you can access the singleton instance with B, in the second case with B.aType.
In the second case, no explicit declaration of the apply method is needed.
Pick what you like.
The essential message is: You don't need a trait if you just define one simple method.
That's what Scala functions are for.
The list type might look like this:
private val aList:ListBuffer[()=>Unit] = ???
(By the way: Why not declare it as Seq[()=>Unit]? Is it important to the caller that it is a ListBuffer and not some other kind of sequence?)
Your worker might then look like this:
abstract class Worker {
def aType:()=>Unit // no need for the `get` prefix here, or the empty parameter list
def do() {aType()}
}
Note that now the Worker type has become a class that offers a method that invokes a function.
So, there is really no need to have a Worker class.
You can just take the function (aType) directly and invoke it, just so.
If you always want to call the implementation in object B, well - just do that then.
There is no need to wrap the call in instances of other types.
Your example class B just forwards the call to the B object, which is really unnecessary.
There is no need to even create an instance of B.
It does have the private member variable creator, but since it's never used, it will never be accessed in any way.
So, I would recommend to completely remove the class B.
All you need is the type ()=>Unit, which is exactly what you need: A function that takes no parameters and returns nothing.
If you get tired of writing ()=>Unit all the time, you can define a type alias, for example inside the package object.
Here is my recommentation:
type SideEffect = ()=>Unit
Then you can use SideEffect as an alias for ()=>Unit.
That's all I can make of it.
It looks to me that this is probably not what you were looking for.
But maybe this will help you a little bit along the way.
If you want to have a more concrete answer, it would be nice if you would clarify the question.
object B doesn't really have much to do with class B aside from some special rules.
If you wish to reuse that doSomething method you should just reuse the implementation from the object:
class B {
def doSomething() = B.doSomething()
}
If you want to specify object B as a specific instance of class B then you should do the following:
object B extends B("some particular creator") {
...
}
You also do not need override modifiers although they can be handy for compiler checks.
The notion of a companion object extending a trait is useful for defining behavior associated with the class itself (e.g. static methods) as opposed to instances of the class. In other words, it allows your static methods to implement interfaces. Here's an example:
import java.nio.ByteBuffer
// a trait to be implemented by the companion object of a class
// to convey the fixed size of any instance of that class
trait Sized { def size: Int }
// create a buffer based on the size information provided by the
// companion object
def createBuffer(sized: Sized): ByteBuffer = ByteBuffer.allocate(sized.size)
class MyClass(x: Long) {
def writeTo(buffer: ByteBuffer) { buffer.putLong(x) }
}
object MyClass extends Sized {
def size = java.lang.Long.SIZE / java.lang.Byte.SIZE
}
// create a buffer with correct sizing for MyClass whose companion
// object implements Sized. Note that we don't need an instance
// of MyClass to obtain sizing information.
val buf = createBuffer(MyClass)
// write an instance of MyClass to the buffer.
val c = new MyClass(42)
c.writeTo(buf)

Specifying the requirements for a generic type

I want to call a constructor of a generic type T, but I also want it to have a specific constructor with only one Int argument:
class Class1[T] {
def method1(i: Int) = {
val instance = new T(i) //ops!
i
}
}
How do I specify this requirement?
UPDATE:
How acceptable (flexible, etc) is it to use something like this? That's a template method pattern.
abstract class Class1[T] {
def creator: Int => T
def method1(i: Int) = {
val instance = creator(i) //seems ok
i
}
}
Scala doesn't allow you to specify the constructor's signature in a type constraint (as e.g. C#).
However Scala does allow you to achieve something equivalent by using the type class pattern. This is more flexible, but requires writing a bit more boilerplate code.
First, define a trait which will be an interface for creating a T given an Int.
trait Factory[T] {
def fromInt(i: Int): T
}
Then, define an implicit instance for any type you want. Let's say you have some class Foo with an appropriate constructor.
implicit val FooFactory = new Factory[Foo] {
def fromInt(i: Int) = new Foo(i)
}
Now, you can specify a context bound for the type parameter T in the signature of Class1:
class Class1[T : Factory] {
def method1(i: Int) = {
val instance = implicitly[Factory[T]].fromInt(i)
// ...
}
}
The constraint T : Factory says that there must be an implicit Factory[T] in scope. When you need to use the instance, you grab it from implicit scope using the implicitly method.
Alternatively, you could specify the factory as an implicit parameter to the method that requires it.
class Class1[T] {
def method1(i: Int)(implicit factory: Factory[T]) = {
val instance = factory.fromInt(i)
// ...
}
}
This is more flexible than putting the constraint in the class signature, because it means you could have other methods on Class1 that don't require a Factory[T]. In that case, the compiler will not enforce that there is a Factory[T] unless you call one of the methods that requires it.
In response to your update (with the abstract creator method), this is a perfectly reasonable way to do it, as long as you don't mind creating a subtype of Class1 for every T. Also note that T will need to be a concrete type at any point that you want to create an instance of Class1, because you will need to provide a concrete implementation for the abstract method.
Consider trying to create an instance of Class1 inside another generic method. When using the type class pattern, you can extend the necessary type constraint to the type signature of that method, in order to make this compile:
def instantiateClass1[T : Factory] = new Class1[T]
If you don't need to do this, then you might not need the full power of the type class pattern.
When you create a generic class or trait, the class does not gain special access to the methods of whatever actual class you might parameterise it with. When you say
class Class1[T]
You are saying
This is a class which will work with unspecified type T.
Most of its methods will take instances of type T as a parameter or return T.
Any variance annotations or type bounds attached to the type parameter will be applied whenever it appears as a parameter of one of Class1's methods.
There is no such thing as type "Class1" but there may be an arbitrary number of derived classes of type "Class1[something]"
That's all. You get no special access to T from within Class1, because Scala does not know what T is. If you wanted Class1 to have access to T's fields and methods, you should have extended it or mixed it in.
If you want access to the methods of T (without using reflection), you can only do that from within one of Class1's methods which accepts a parameter of type T. And then you will get whichever version of the method belongs to the specific type of the actual object which is passed.
(You can work around this with reflection, but that is a runtime solution and absolutely not typesafe).
Look at what you are trying to do in your original code snippet...
You have specified that Class1 can be parameterised with any arbitrary type.
You want to invoke T with a constructor which takes a single Int parameter
But what have you done to promise the Scala compiler that T will have such a constructor? Nothing at all. So how can the compiler trust this? Well, it can't.
Even if you added an upper type bound, requiring that T be a subclass of some class which does have such a constructor, that doesn't help; T might be a subclass which has a more complex constructor, which calls back to the simpler constructor. So at the point where Class1 is defined, the compiler can have no confidence about the safety of constructing T with that simple method. So that call cannot be type-safe.
Class-based OO isn't about conjuring unknown types out of the ether; it doesn't let you plunge your hand into a top-hat-shaped class loader and pull out a surprise. It allows you to handle arbitrary already-created instances of some general type without knowing their specific type. At the point where those objects are created, there's no ambiguity at all.

Difference between object and class in Scala

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