class Animal
constructor: (#name) ->
move: (meters) ->
alert #name + " moved #{meters}m."
class Snake extends Animal
move: ->
alert "Slithering..."
super 5
So I was going through the CoffeeScript docs and ran into the above illustration of class extension. Can someone explain to me exactly what is happening when the line super 5 is executed? I vaguely understand it is calling the super class's definition of move with the argument, 5, but what would the output look like if one called mySnake.move assuming my snake's name is Robert?
super will call the move method on the base class. Specifically, it will call the Animal move method and pass in 5 as the meters parameter.
If you run the example on the CoffeeScript page, you should see an alert with "Sammy the Python moved 5m."
super is useful when your subclass has its own logic to run in addition to the base class implementation. You can place super right at the beginning of the method, or after additional code runs. Order might matter depending on the logic that's in place.
Related
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__()
...
I wanna change my titlebar in a dynpro when a specific class method is triggered. So I thought I could call a function in my report, where my dynpro is located, which changes uses the 'SET TITLE' to change the titlebar content.
Is this possible and how exactly? Or is there even a better way?
Thanks!
Use SET TITLEBAR during the PBO processing - it doesn't matter if it is used from a method, a FORM or the module directly. I'd recommend having one single SET TITLEBAR statement that is always called at the same point in the control flow instead of littering the code with SET TITLEBAR statements for better maintainability.
Recently I needed to implement something similar so I defined a class hierarchy where I created an abstract class with a method 'CALL_DYNPRO'. This method is intended to load an specific dynpro in the concrete classes.
So, depending on an action I defined internally I generate the appropriate instance and then the method 'CALL_DYNPRO' loads the dynpro I created with their own gui statuses and titles.
The following is more or less the code I created.
********************************* The abstract class
class lc_caller definition abstract.
public section.
methods: call_dynpro.
endclass.
class lc_caller implementation.
method call_dynpro.
endmethod.
endclass.
********************************* The concrete classes
class lc_caller_01 definition inheriting from lc_caller.
public section.
methods: call_dynpro redefinition.
endclass.
class lc_caller_01 implementation.
method call_dynpro.
call screen 101.
endmethod.
endclass.
class lc_caller_02 definition inheriting from lc_caller.
public section.
methods: call_dynpro redefinition.
endclass.
class lc_caller_02 implementation.
method call_dynpro.
call screen 102.
endmethod.
endclass.
********************************* Factory
class caller definition.
public section.
class-methods call importing i_type type char01
returning value(r_instance) type ref to lc_caller.
endclass.
class caller implementation.
method call.
data: caller1 type ref to lc_caller_01,
caller2 type ref to lc_caller_02.
case i_type.
when '0'.
create object caller1.
r_instance = caller1.
when '1'.
create object caller2.
r_instance = caller2.
when others.
endcase.
endmethod.
endclass.
start-of-selection.
data obj type ref to lc_caller.
obj = caller=>call( '0' ).
obj->call_dynpro( ).
This is the code inside the PBOs.
Dynpro 101
module status_0101 output.
set pf-status 'FORM1'.
set titlebar 'VER'.
endmodule.
Dynpro 102
module status_0102 output.
set pf-status 'FORM2'.
set titlebar 'TRA'.
endmodule.
If tomorrow I need to call another dynpro I create it and then code the concrete class to load it.
Very straightforward and works very nice.
Hope it helps.
I am trying to call the super constructor from a class using a method. The whole setup looks like this:
class Straight(hand: Hand) extends Combination(Straight.makeHandAceLowIfNeeded(hand), 5)
object Straight {
private def makeHandAceLowIfNeeded(hand: Hand): Hand = {
...
}
}
While this does compile, it has some rather odd runtime behaviour. While debugging, I noticed that the Straight instances have the "hand" property defined twice. Can somebody tell me what is going on, and what the proper way is to call the super constructor with different arguments?
In my use case, I want to call the super constructor with a modified hand in which I replaced a card compared to the original constructor argument.
Debugger screenshot with duplicate field:
.
It's a perfectly fine way to call the superclass constructor. These are two private fields and they don't conflict, though you can rename one of them to avoid confusion during debugging (or if you want to access the superclass' value from the subclass). However, the field should only be generated for a class parameter if it's used outside a constructor, and in your case it doesn't appear to be. Did you simplify the definition of Straight?
It's rather a meta question, so its not that I don't understand polymorphism.
Suppose you have a class and its super class.
The super class has a method print, it prints out "Super".
The sub class overrides this method it prints out "Sub".
If you create two instances, one declared as the super class, the other one as the actual class.
SuperClass superClass = new SubClass();
SubClass subClass = new SubClass();
Now if you work with Eclipse, if you type superClass. and hit ctrl+space, in the list Eclipse says, that the print method belongs to SuperClass.
If you do the same with subClass, eclipse recommends the print method of SubClass.
If you simply use:
superClass.print();
subClass.print();
Then, of course the output will be: SubSub. As it should be.
Would you consider this a mistake in Eclipse? Or there is an explanation for this? Thanks!
Think of code completion as working on the static view, the same view that is also taken by the compiler: completing after superClass. lets you add print() because SuperClass has a method print(). Seeing print() in SuperClass ensures that superClass.print() can be evaluated.
This view is different from the runtime view (what your program actually does), where the JVM will find an instance of SubClass and via dynamic binding invoke the sub class version of print().
Editor, completion and compiler use the static view. If you are interested in the runtime view, you'd typically use the debugger. As a middle road, you may select any method invocation and press Ctrl+T, which gives you the list of all implementations that could possibly be invoked at runtime via this method invocation. But nothing short of the debugger will definitely tell you, which version will actually be called at runtime.
When you ctrl space on superClass, how can we expect IDE to identify for which SubClass u have assigned the variable.
If you have two sub class for a super class, do you expect it to show all the methods from both the sub classes.
What happens if it is not final?
What happens if it s a class level variable where IDE Cannot make sure at that point of execution, which sub class instance being hold.
If you need methods from sub class, then add a instance check, type cast and say ctrl space.
In CoffeeScript, I'd like to be able to assign the super method to a variable without calling it.
class a
one: ->
class b extends a
one: ->
mySuper = super
However doing the following actually calls the super method rather than returning it - here's the compiled code:
return mySuper = b.__super__.one.apply(this, arguments);
How do I actually assign the super method to a variable rather than calling it?
I know I could do:
class b extends a
one: ->
mySuper = b.__super__.one
But it isn't that clean.
Coffee script provides no syntax sugar for this use case. So do it yourself.
I would do it like this:
class B extends A
one: ->
mySuper = A::one
mySuper.call this # calls the saved super method
Example
:: is a shorthand for prototype. So A::one compiles to A.prototype.one which is where your super method actually is.
But this seems like a red flag to me. I can't think of a case where this would be a good idea. I'd wager it's not part of the language because if you design your classes properly, you shouldn't need this. You say you want something clean, but the thing you want to do here I wouldn't consider clean at all.