简体   繁体   中英

Do scala classes have “self” like Python?

For example if I have

object Solution {
    class myClass(A: Array[Int]){
        val something: Int = A.length;
        val another: Int = something/2;
        val someName = "blah"
 ...
 ...

Do these variables "exist" only for a particular instance of myClass or are they "class-wide" variables shared among all objects? If it's the latter, how do I make these variables object-only?

Yes, and it is implemented as this , like in Java or C++. You don't have to pass it explicitly at the method call, like in python.

Then what you're creating in your example are instance variables, also called members. They belong to instances of the class, ie they are not shared on all objects of all the same class ( class variables ). For the latter, you might want to use the companion scheme .

Finally, you might want to give some more reading about scala, like this tutorial here , or the one for python devs courtesy of @IanAuld or run the scala course on coursera which is offered by the creators of scala.

And BTW, welcome on Stack Overflow!


edit:

So the way I have it set up here in Scala are instance variables, whereas if I had done this same general approach (in terms of placement) in Python, they'd be class variables? Or are you saying I have to add "this" somewhere to make them instance variables?

I see where you're getting confused. Python and Scala are very different in their approaches to object oriented programing. First let's talk about python a bit:

python

Python has been designed with the idea that classes (and modules, btw) are dict , in earlier versions of python you could even access the members of the class through the myclass.__dict__ member, and today, even though that dict is "hidden" by the implementation, it's still accessible through getattr and setattr .

This idea is central to how python works with classes, as everything is done through monkey patching , ie changing, and actually defining, the class definition at runtime.

class Foo:
    pass
foo = Foo()
foo.bar = 1
print(foo.bar)

Another thing that is fundamental in python is that everything is explicit. This is why when you declare a method, you pass explicitly the reference of the current class as a parameter to the method:

class Foo:
    def foobar(self):
        self.bar = 1
print(foo.bar)

but that is actually equivalent to doing:

class Foo:
    pass
def foobar(self):
    self.bar = 1
foo = Foo()
foobar(foo)
print(foo.bar)

and the following behaviour illustrate quite well what monkey patching is about:

class Foo:
    def foobar(self):
        print(self.bar)
foo = Foo()
foo.bar = 1
foo.foobar() # prints 1

so when you're actually defining members in python, what you're really doing is monkey patching the current instance with new members.

Now, when you do class instances , what you do is actually behaving like the following, if we use the dict representation I told you about:

Foo = dict(a=1, b=[2]) # class definition with class variables
foo = Foo.copy()       # create instance
foo['b'].append(3)     # use a class variable's instance
print(Foo['b']) # prints: [2,3]

All in all, python has a very special approach to OOP, that is entirely based on the ideas that class behave a bit like dict and that they shall be monkey patched to be defined (which is why when you create a class, the convention is to declare all your members in your constructor). And those are reasons why python is not considered a "pure" object oriented language (which is just a property of the language, not a qualification).

Scala

Scala is being defined as a pure functional and pure object oriented language. And those two properties of the language makes it very, very different from python. I'm not gonna get into length into explaining functional programing in depth, but I highly recommend you to follow a course and read books about it and Scala to have a good grip at it.

So in Scala when you define a class, you can do the following (example courtesy of the tutorial I linked):

class Square {
    var x: Double = 0
    var y: Double = 0
    var width: Double = 0
    var height: Double = 0
    def area(): Double = width * height
}

so here you defined instance variables and you give them a "default" value, which is what you'd define in python within the __init__() constructor. And then you define a method.

But because scala is functional, you can have another reading at the class definition:

class Square(
    private var x: Double,
    private var y: Double,
    private var width: Double,
    private var height: Double
  ) {
    def area(): Double = width * height
  }

Square is a function which takes parameters, and returns an instance that has methods, being defined within the scope of that function. So then, the outer "function" is actually a constructor, and the inner functions are the methods.

Now, there's no actual class variables existing in scala, and to do so, you might prefer to use the companion design pattern (cf the SO answer link about it).

But incidentally, because the property of the someName variable you're using in your example:

class myClass(A: Array[Int]){
    val something: Int = A.length;
    val another: Int = something/2;
    val someName = "blah"

your someName variable is non mutable. What that means is that you cannot modify it within the instances, and thus it is the same for all your instances. So somehow, it looks like class variable, even though it's not, they really are instance variables.

Like my dict example in python, this is not entirely exact as there's much more to know about those mechanisms — I'm not even scratching the surface here, but it works for the purpose of demonstrating the huge difference there is between Scala — a functional/object language, and python — a 🐒-patching/object language.

Now going from a procedural paradigm language to a functional one quite a big step, it feels like learning again to develop, but it's definitely worth it, as it's going to teach you a different way of thinking your programs, and not only you learn a new language and a new paradigm, but it's also going to make you develop better in the languages you already know by having better practices and caring more about typing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM