class A(object):
def foo(self):
print 'A'
class B(A):
def foo(self):
print 'B'
class C(B):
pass
c = C()
c.foo()
>>> B
I want to call the foo() method of class A. So how can I call this foo() method so that it will print 'A'
To directly answer your question, you could define C like this:
class C(B):
def foo(self):
A.foo(self)
However, a better question might be: why are you trying to do this? A class needing to access functions from the, erm, "grandparent" that were also defined in the parent class is a pretty good sign that your inheritance model is not ideal. For example: does C need anything from B; could it inherit directly from A?
Related
Hi I have a case class A which contains variables pointing to another class B (with companion object, which has variables pointing to yet another class C which also has companion object). class B and C are from other libraries. What is the easier way that I could serialize my case class A?
case class A() {
val b = B
}
//B & C are defined in a library that I have no control of
object B {
val c = C
}
class B{
...
}
object C{
...
}
class C{
...
}
If these classes are already Serializable, you don't need to do anything special, so the rest of the answer assumes they aren't.
If these fields can be reconstructed from others, mark them as #transient and implement readObject (as described in http://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html) to restore them. Unfortunately, you can't initialize vals in readObject and will have to write something like
case class A() {
private var _b = B
def b = _b
}
If they can't, you need to store something they can be restored from in writeObject as well.
Finally, you can use one of the third-party serialization libraries like Kryo or Scala Pickling, because basically all of them allow to add support for types not under your control (otherwise they couldn't work with the types in standard Java library!)
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)
I am new to scala. I was learning traits and it seems that they can have concrete methods. Here is the code I have written.
trait A{
def print : Unit = {
println("I am in A")
}
}
trait B{
def print : Unit = {
println("I am in B")
}
}
trait C {
def print : Unit = {
println("I am in C")
}
}
class D extends A with B with C{
}
object Main extends App {
val d: D = new D
d.print
}
It is giving a compilation error obviously. The compiler is asking me to override the print method in D. I don't want to write a new method. I just want to choose C's print method over others. Is there any way I can choose only C's print method? I hope I have made myself clear. I am sorry if the question sounds stupid. I am trying to learn. Thanks in advance.
#S.K, so the last trait I mix in is the super class?
If you look at the documention of Scala trait, whenever scala compiler see any class with multiple parent scala compiler will place all the classes in stackable form.
so If A extends B with C will become --> A->B->C and when you invoke super from you base class A it will consider method like C->B (C then B).
same way if you make A extends C with B will become --> A->C->B and when you invoke it compiler will consider B->C (B then C).
Please see more detials on scala trait stackable at below link.
Scala's Stackable Trait Pattern
I am agree with S.K what is a problem to override in class D.
One way you are extending your D class with C and without overriding how can you get the handle of method in C?
You have to override in order to call it's method.
I know Scala can only mixin traits, it makes sense for dependency injection and cake pattern. My question is why I can still declare a class which need another "class" but not trait.
Code:
class C
class D { self : C =>}
This is still complied successfully. I thought it should failed compiled, because at this point how can new instance D (C is class not trait).
Edit:
when try to instantiate D:
new D with C //compilation fail class C needs to be a trait to be mixed in.
You should explicitly make class D to extends C as follows:
class C
class D extends C { self: C => }
Furthermore, you can refer to the post Does a class with a self type of another class make sense?, which explains this problem clearly.
I have three coffeescript classes, set up like this:
class A
class C extends A
class B
so that the prototype chain looks like this:
A -> C
B
and I need the prototype chain to look like this:
A -> B -> C
The catch being that I can't touch the definitions of A and C.
What I'd like to do is make an inject function that can be called like this:
inject B, C
that injects B into C's prototype chain before A, and then set up B's prototype chain to whatever C's was before the injection.
I thought this would be simple, something like
C extends (B extends C.prototype)
But unfortunately, things aren't quite that simple, due to all the prototype/__super__ magic that coffeescript does. Does anyone know how to inject into the prototype chain such that it's basically like you said class C extends B and class B extends A in the first place?
Many thanks.
Clarification: The below code DOES NOT WORK, because the properties fail to be copied over.
class A
foo: 1
class B
bar: 2
class C extends A
baz: 3
B extends A
C extends B
c = new C
console.log c.foo
console.log c.bar
console.log c.baz
[Update: I originally answered that C extends B; B extends A would work. This does indeed make C instanceof B and B instanceof A become true, but it doesn't copy prototypal properties as desired. So, I've rewritten the answer.]
Let's walk through this:
class A
foo: 1
class B
bar: 2
class C extends A
baz: 3
At this point, C::foo is 1 and C::baz is 3. If we then run
C extends B
that overwrites C's existing prototype with an instance of B (child.prototype = ...), so only C::bar is defined.
This doesn't happen when we use the class X extends Y syntax because properties are attached to X's prototype only after its prototype is overwritten. So, let's write a wrapper around extends that saves existing prototype properties, then restores them:
inherits = (child, parent) ->
proto = child::
child extends parent
child::[x] = proto[x] for own x of proto when x not of child::
child
Applying this to our example:
inherits B, A
inherits C, B
console.log new C instanceof B, new B instanceof A # true, true
console.log B::foo, B::bar, B::baz # 1, 2, undefined
console.log C::foo, C::bar, C::baz # 1, 2, 3
If you'd like to learn more about the inner workings of CoffeeScript classes, you might want to check out my book on CoffeeScript, published by the fine folks at PragProg. :)