I have been trying to make a simple player class that contains all of the important player functions in python. I was just getting into the pygame module, when I noticed a class used parentheses. I took the time to learn what a class does in python, but, couldn't find why parentheses are used after for a class. Here is my main code.
class plr(pygame.sprite.Sprite):
def __init__(self):
plr.__init__(self)
self.image = pygame.Surface((20,20))
self.image.fill(black)
Any explanations?
The parentheses at the end of the line in a class statement surround the base classes of the class you're defining. In the common case, there's just one base class (which may be object if no other base class is needed). In Python 3, you can omit the base class and object will be used by default, but you should always explicitly name object (or some subclass) as a base in Python 2, or you'll get an "old-style" class which is something you probably don't want. (Old style classes are quite thoroughly obsolete and not worth learning about if you're new to Python. They don't exist any more in Python 3.)
Specifying a base class lets your new class inherit methods and other behavior from the base class. Inheritance is a key part of Object Oriented Programming, so you'll probably encounter it quite a bit!
In your specific example, the plr class is inheriting from pygame.sprite.Sprite. That means you can call Sprite methods on instances of plr, and they'll usually just work. You can override some of them, if you want to customize your object's behavior.
I do see an error in your code. The __init__ method you've written will recurse infinitely, since it calls plr.__init__, which is itself! You probably wanted it to call pygame.sprite.Sprite.__init__, which is overriding. You can make that call either with the long name I mentioned above, or by using super (which is nicer). Try:
class plr(pygame.sprite.Sprite):
def __init__(self):
super(plr, self).__init__()
...
Related
What does the override do here? After deleting override, I can still compile the program.
abstract class Animal {
def name: String
}
class Cat extends Pet {
override def name: String = "Cat"
}
Adapted from Tour of Scala: Upper Type Bounds:
https://docs.scala-lang.org/tour/upper-type-bounds.html
You are right, this is a particular case where removing it does not affect the program. Why override is allowed here is for various flexibility reasons:
say you want to add an implementation in the parent class Animal - that would work without affecting the behavior of Cat because you used the prophylactic
override in Cat to prevent that idea from affecting your extended class. So the subclass becomes just a little bit less tightly-coupled from your base class in this case.
say someone else deletes the abstract method name or renames it in the parent class (without knowing that method is being overridden). This would raise compile errors in all classes that overridden it, to he/she will know that this change should be thoroughly thought before being done, as it will affect the interface and the way clients interact with your code.
also it makes the compiler help you catch typos in subclasses: say you created another subclass and add a different method but misspell name for something else, say nme - you'll see that if you used override the compiler will warn you that nme does not override anything in the base class. (Thanks compiler!)
for me personally, using override in subclasses acts as a marker so I know that this method is also defined in the base class, without having to manually check the base class, which usually resides in a different file.
So it's more of a "best practice" thing rather than a necessity in this case, and everyone is free to use it as they see fit.
It seems to me that I can make just about anything using object, trait, abstract class and in rare occasions, case class. Most of this is in the form object extends trait. So, I'm wondering, when should I, if ever, use a plain, standard class?
This is not a right place to ask this question
Looks like you are new Scala
Class is a specification for something(some entity) you want to model . It contains behavior and state
There is only one way to declare so called regular class using keyword class
Both trait and abstract class are used for inheritance.
trait is used for inheritance (generally to put common behavior in there). trait is akin to interface in Java. multiple inheritance possible with traits but not abstract class.
A class can extends one class or abstract class but can mixin any number of traits. Traits can have behavior and state.
case class is a nothing but a class but compiler produces some boilerplate code for us to make things easy and look good.
object is used when you want to declare some class but you want to have single instance of the class in the JVM (remember singleton pattern).
If an object performs stateful computations on its members i.e. its members are declared with vars;
Or, even if its member are only declared with vals but those vals store mutable data structures which can be edited in place, then it should be an ordinary (mutable) class akin to a Java mutable object.
The idiomatic way of using Case classes in Scala is as immutable types i.e. all the constructor arguments are vals. We could use vars but then we lose the advantages of case classes like equality comparisons will break over time.
Some advise from Programming in Scala by Odersky et al on deciding between using traits, abstract classes and concrete classes:
If the behavior will not be reused, then make it a concrete class. It is not reusable behavior after all.
If it might be reused in multiple, unrelated classes, make it a trait.
Only traits can be mixed into different parts of the class hierarchy.
If you want to inherit from it in Java code, use an abstract class.
Since traits with code do not have a close Java analog, it tends to be
awkward to inherit from a trait in a Java class. Inheriting from a
Scala class, meanwhile, is exactly like inheriting from a Java class.
As one exception, a Scala trait with only abstract members translates
directly to a Java interface, so you should feel free to define such
traits even if you expect Java code to inherit from it. See Chapter 29
for more information on working with Java and Scala together.
If you plan to distribute it in compiled form, and you expect outside
groups to write classes inheriting from it, you might lean towards
using an abstract class. The issue is that when a trait gains or loses
a member, any classes that inherit from it must be recompiled, even if
they have not changed. If outside clients will only call into the
behavior, instead of inheriting from it, then using a trait is fine.
If efficiency is very important, lean towards using a class. Most Java
runtimes make a virtual method invocation of a class member a faster
operation than an interface method invocation. Traits get compiled to
interfaces and therefore may pay a slight performance overhead.
However, you should make this choice only if you know that the trait
in question constitutes a performance bottleneck and have evidence
that using a class instead actually solves the problem.
If you still do not know, after considering the above, then start by
making it as a trait. You can always
change it later, and in general using a trait keeps more options open.
Starting with 2.10, -Xlint complains about classes defined inside of package objects. But why? Defining a class inside a package object should be exactly equivalent to defining the classes inside of a separate package with the same name, except a lot more convenient.
In my opinion, one of the serious design flaws in Scala is the inability to put anything other than a class-like entity (e.g. variable declarations, function definitions) at top level of a file. Instead, you're forced to put them into a separate ''package object'' (often in package.scala), separate from the rest of the code that they belong with and violating a basic programming rule which is that conceptually related code should be physically related as well. I don't see any reason why Scala can't conceptually allow anything at top level that it allows at lower levels, and anything non-class-like automatically gets placed into the package object, so that users never have to worry about it.
For example, in my case I have a util package, and under it I have a number of subpackages (util.io, util.text, util.time, util.os, util.math, util.distances, etc.) that group heterogeneous collections of functions, classes and sometimes variables that are semantically related. I currently store all the various functions, classes, etc. in a package object sitting in a file called io.scala or text.scala or whatever, in the util directory. This works great and it's very convenient because of the way functions and classes can be mixed, e.g. I can do something like:
package object math {
// Coordinates on a sphere
case class SphereCoord(lat: Double, long: Double) { ... }
// great-circle distance between two points
def spheredist(a: SphereCoord, b: SphereCoord) = ...
// Area of rectangle running along latitude/longitude lines
def rectArea(topleft: SphereCoord, botright: SphereCoord) = ...
// ...
// ...
// Exact-decimal functions
class DecimalInexactError extends Exception
// Format floating point value in decimal, error if can't do exactly
formatDecimalExactly(val num: Double) = ...
// ...
// ...
}
Without this, I would have to split the code up inconveniently according to fun vs. class rather than by semantics. The alternative, I suppose, is to put them in a normal object -- kind of defeating the purpose of having package objects in the first place.
But why? Defining a class inside a package object should be exactly equivalent to defining the classes inside of a separate package with the same name,
Precisely. The semantics are (currently) the same, so if you favor defining a class inside a package object, there should be a good reason. But the reality is that there is at least one good reason no to (keep reading).
except a lot more convenient
How is that more convenient?
If you are doing this:
package object mypkg {
class MyClass
}
You can just as well do the following:
package mypkg {
class MyClass
}
You'll even save a few characters in the process :)
Now, a good and concrete reason not to go overboard with package objects is that while packages are open, package objects are not.
A common scenario would be to have your code dispatched among several projects, with each project defining classes in the same package. No problem here.
On the other hand, a package object is (like any object) closed (as the spec puts it "There can be only one package object per package"). In other words,
you will only be able to define a package object in one of your projects.
If you attempt to define a package object for the same package in two distinct projects, bad things will happen, as you will effectively end up with two
distinct versions of the same JVM class (n our case you would end up with two "mypkg.class" files).
Depending on the cases you might end up with the compiler complaining that it cannot find something that you defined in the first version of your package object,
or get a "bad symbolic reference" error, or potentially even a runtime error. This is a general limitation of package objects, so you have to be aware of it.
In the case of defining classes inside a package object, the solution is simple: don't do it (given that you won't gain anything substantial compared to just defining the class as a top level).
For type aliase, vals and vars, we don't have such a luxuary, so in this case it is a matter of weighing whether the syntactic convenience (compared to defining them in an object) is worth it, and then take care not to define duplicate package objects.
I have not found a good answer to why this semantically equivalent operation would generate a lint warning. Methinks this is a lint bug. The only thing that I have found that must not be placed inside a package object (vs inside a plain package) is an object that implements main (or extends App).
Note that -Xlint also complains about implicit classes declared inside package objects, even though they cannot be declared at package scope. (See http://docs.scala-lang.org/overviews/core/implicit-classes.html for the rules on implicit classes.)
I figured out a trick that allows for all the benefits of package objects without the complaints about deprecation. In place of
package object foo {
...
}
you can do
protected class FooPackage {
...
}
package object foo extends FooPackage { }
Works the same but no complaint. Clear sign that the complaint itself is bogus.
In Eclipse plugin, I could create scala Object, APP and class. But what's the difference among these 3. Basically, for object, I implement def main(...), then I could run it. But in class, it seems it is similar to normal Java class, but what's the meaning scala APP, it creates a object which extends APP. What's this meant for?
In the JVM, the starting point of the application is a static method main(String[] args), in some class given to the JVM.
In scala there is no static methods, the equivalent is to put a method in an object (as opposed to class). Putting your main method in a class will not work, it is the same as not marking the method static in java.
App is a helper that allows not to write the main method, and put the code directly in the object body.
object MyApp extends App {
doStuff
}
does the same thing as
object MyApp {
def main(args: Array[String]) {doStuff}
}
(arguments can be used in doStuff under the name args)
Scala has no static methods, so public static void main is not available for classes.
Objects are single entries that better fits the "common to every object of a class" scope. So, oversimplifying things, you can think of Object as a Singleton which "acts as an only-static container" (quote from Scala for Java Refugees). If you think about it, that's the perfect place for a main method, and that's why they are declared there.
The App trait just explores the fact that instructions written inside the body of an Object are executed as part of its initialization. It couples this standard behaviour with some delayed initialization tricks to use the body of an object as the main method. So, you can think about it as a short alternative syntax to create a application entry point. It replaced the naive Application trait that had a lot of shortcomings.
Which one of the two to use is really a matter of taste, but I tend to stick with the more familiar main method syntax.
Cheers,
Ok, I'll explain why I ask this question. I begin to read Lift 2.2 source code these days.
It's good if you happened to read lift source code before.
In Lift, I found that, define inner class and inner trait are very heavily used.
object Menu has 2 inner traits and 4 inner classes. object Loc has 18 inner classes, 5 inner traits, 7 inner objects.
There're tons of codes write like this. I wanna to know why the author write like this.
Is it because it's the author's
personal taste or a powerful use of
language feature?
Is there any trade-off for this kind
of usage?
Before 2.8, you had to choose between packages and objects. The problem with packages is that they cannot contain methods or vals on their own. So you have to put all those inside another object, which can get awkward. Observe:
object Encrypt {
private val magicConstant = 0x12345678
def encryptInt(i: Int) = i ^ magicConstant
class EncryptIterator(ii: Iterator[Int]) extends Iterator[Int] {
def hasNext = ii.hasNext
def next = encryptInt(ii.next)
}
}
Now you can import Encrypt._ and gain access to the method encryptInt as well as the class EncryptIterator. Handy!
In contrast,
package encrypt {
object Encrypt {
private[encrypt] val magicConstant = 0x12345678
def encryptInt(i: Int) = i ^ magicConstant
}
class EncryptIterator(ii: Iterator[Int]) extends Iterator[Int] {
def hasNext = ii.hasNext
def next = Encrypt.encryptInt(ii.next)
}
}
It's not a huge difference, but it makes the user import both encrypt._ and encrypt.Encrypt._ or have to keep writing Encrypt.encryptInt over and over. Why not just use an object instead, as in the first pattern? (There's really no performance penalty, since nested classes aren't actually Java inner classes under the hood; they're just regular classes as far as the JVM knows, but with fancy names that tell you that they're nested.)
In 2.8, you can have your cake and eat it too: call the thing a package object, and the compiler will rewrite the code for you so it actually looks like the second example under the hood (except the object Encrypt is actually called package internally), but behaves like the first example in terms of namespace--the vals and defs are right there without needing an extra import.
Thus, projects that were started pre-2.8 often use objects to enclose lots of stuff as if they were a package. Post-2.8, one of the main motivations has been removed. (But just to be clear, using an object still doesn't hurt; it's more that it's conceptually misleading than that it has a negative impact on performance or whatnot.)
(P.S. Please, please don't try to actually encrypt anything that way except as an example or a joke!)
Putting classes, traits and objects in an object is sometimes required when you want to use abstract type variables, see e.g. http://programming-scala.labs.oreilly.com/ch12.html#_parameterized_types_vs_abstract_types
It can be both. Among other things, an instance of an inner class/trait has access to the variables of its parent. Inner classes have to be created with a parent instance, which is an instance of the outer type.
In other cases, it's probably just a way of grouping closely related things, as in your object example. Note that the trait LocParam is sealed, which means that all subclasses have to be in the same compile unit/file.
sblundy has a decent answer. One thing to add is that only with Scala 2.8 do you have package objects which let you group similar things in a package namespace without making a completely separate object. For that reason I will be updating my Lift Modules proposal to use a package object instead of a simple object.