I'm reading an android app and do not understand why the constructor in the ListeningQuestion.java uses this.variable = variable in its own constructor, but only variable = variable (no this) in the ListeningQuestionItem.java. They both have variable declared as private in the respective class. Why the differences? Any help?
The constructor as declared in ListeningQuestion.java you are looking -
public ListeningQuestion(String listeningFileID, String listeningSoundAddress, String listeningImageAddress,
ArrayList<ListeningQuestionItem> listeningQuestionItems) {
this.listeningFileID = listeningFileID;
this.listeningSoundAddress = listeningSoundAddress;
this.listeningImageAddress = listeningImageAddress;
this.listeningQuestionItems = listeningQuestionItems;
}
If we see the constructor, the name of the parameter is same as the name of private variable.
By specifying, this, I am explicitly asking to assign the value of parameter to the local variable. This signifies the instance to current class.
In case I do not use this keyword, the value will not be assigned to local private variable, but re assigned to the parameter value itself, because it has narrower scope.
It is a common convention to assign the parameter values to local variable this way.
Some stuff here and here about using this keyword
Now if you see the constructor of ListeningQuestionItem.java,
The names of parameters and local variable, differs by case. And because there is no ambiguity, you can assign the value to private variable, without using this, as -
ListeningQuestionID = listeningQuestionID
As per https://docs.oracle.com/javase/tutorial/java/javaOO
Within an instance method or a constructor, this is a reference to the current object — the object whose method or constructor is being called.
An object has state, and in case there are same local variables of same name as of the instance fields then fields can be accessed using this keyword.
this.listeningFileID = listeningFileID;
In this case there is one instance variable named as listeningFileID which is accessed using this and other is the local variable which is passed as a parameter to the constructor.
Java variable names are case senstive. In the second case
ListeningQuestionContent = listeningQuestionContent;
Observe the first character , the field name is ListeningQuestionContent and the local variable passed as parameter is named as listeningQuestionContent. Here we do not have same names so this js not used (although this is same as this.ListeningQuestionContent = listeningQuestionContent;)
Related
I am trying to use an instance variable as a parameter value in a method, but it is giving me an error. "Parameter initializer is unknown or is not a compile-time constant"
I want to use a non-constant instance variable though, and I assume there has to be some way around this besides calling this method from another method. Here is the code I'm referring to:
public function attack(target:Fighter=this.target):void {
}
What about:
public function attack(target:Fighter):void
{
if(target == null)
target = this.target;
}
and to be honest maybe it's easier to name one of variables _target to avoid confusion. You can use target = _target; instead of this..
You cannot set an optional parameter that way. You can set optional parameters to a default value but not a reference. In this case if you want to keep it optional you could do something like this (or what #George Profenza suggested):
public function attack(target:Fighter=null):void {
target = target ? target : this.target;
}
I see that you marked a correct answer already, but I'll explain that since you are defaulting any null parameters to this.target you would benefit from using this solution so you don't have to pass null each time you call attack() i.e. - you can do attack() instead of attack(null).
Im reading the tutorials here: http://www.adobe.com/devnet/actionscript/learning/oop-concepts/objects-and-classes.html and an on the second paragraph of the Dot Notation section. It uses the 'Sprite' class in ActionScript 3. The tutorial created an instance of the Sprite class and called it myFirstObject. It says..
"Then, using that reference variable and dot notation, values are assigned to the x and visible properties of the instance, and the methods startDrag and stopDrag are called."
I noticed that there are no () after a property. For example:
myFirstObject.x = 300;
compared to a method
myFirstObject.startDrag();
So, what's the difference between a property and method of an instance? I think it would help if I can see the Sprite class but I wasn't able to find it when I tried google'ing.
A property has a Get() and Set() method that allow you to use the same call to get or assign a value. When you assign the property a value, you are calling the Set method. When you retrieve a value, you are using the Get method. Properties automatically call the appropriate Get or Set method based on the operation.
To help you visualize the setup, here is a sample property (VB.Net):
Private _name As String
Public Property Name() As String
Get
Return _name
End Get
Private Set(ByVal value As String)
_name = value
End Set
End Property
To call it, you would use:
MyObject.Name = "Test" <- Sets the name to test
MsgBox("The name is: " & MyObject.Name) <- Gets the value of name
Although the example is in VB.Net, the theory is still the same.
A method, on the other hand, would be the equivalent of either the Get or Set routines. As a method, you have to call it and supply the parameters inside of the parenthesis. Even if it has none, you still need the (). When you want to update a variable, you have to pass values to the method instead of setting it equal to the value.
Here is a similar example:
Private _name As String
Public Function Name(Optional ByVal strName as String = "") as String
If strName <> "" then
_name = strName
End If
Return _name
End Function
Here is a similar example of how to use it:
MyObject.Name("Test") <- Sets the name to test
MsgBox("The name is: " & MyObject.Name()) <- Gets the value of name
Properties and methods are similar in that both are implemented as procedures that accept arguments. In general, properties store data for an object, and methods are actions an object can be asked to perform.
Let's say I have a class with some a couple properties:
public class MyClass {
public var fooProp:*;
public var barProp:Object;
}
What is the difference, practically speaking, between these? Are there variable types I can later assign to fooProp that I cannot assign to barProp?
Only untyped variables can hold the value undefined. Untyped variables are variables that either lack any type annotation, or use the asterisk * symbol for type annotation.
From ActionScript data type descriptors:
In previous versions of ActionScript, a variable with no type
annotation was automatically assigned the Object data type. This is no
longer true in ActionScript 3.0, which now includes the idea of a
truly untyped variable. Variables with no type annotation are now
considered untyped. If you prefer to make it clear to readers of your
code that your intention is to leave a variable untyped, you can use
the new asterisk (*) symbol for the type annotation, which is
equivalent to omitting a type annotation. The following example shows
two equivalent statements, both of which declare an untyped variable:
var x
var x:*
Only untyped variables can hold the value undefined. If you attempt to
assign the value undefined to a variable that has a data type, Flash
Player or Adobe AIR will convert the value undefined to the default
value of that data type. For instances of the Object data type, the
default value is null, which means that Flash Player or Adobe AIR will
convert the value undefined to null if you attempt to assign undefined
to an Object instance.
As an example:
var t:* = undefined;
trace(t); // outputs: undefined
var t:Object = undefined;
trace(t); // outputs: null
In as3 there is a flexible way to change object instance, when calling it.
call or apply members of Function object can be called with specific first arg, and reference say us, that this first arg will be "this" pointer inside function. But i've found it wrong.
I'v write little test, listed below.
public class Test
{
private var name:String = "default";
public var test3:Function = test;
public var test2:Function = function()
{
trace(this.name);
}
public function Test(name:String)
{
this.name = name;
}
public function test():void
{
trace(this.name);
}
}
and tested it.
var tmp:Test = new Test("default");
tmp.test(); //out default
tmp.test.call(new Test("new")); //out default
tmp.test2(); //out default
tmp.test2.call(new Test("new2")); //out new2
tmp.test3(); //out default
tmp.test3.call(new Test("new3")); //out default
So, in anonymous function call we can get right output, but not in case of member function.
maybe it's becouse of ambiguous "this" pointer, that should reffer real object instance for correct work, maybe smth else. I dont now, and as3 reference didnt't describe smth about it.
Finally list of questions:
Why so? By me, it's very strange, and looks like undefined behaviour;
How i can achieve that functionality? How to deceive test function like anonymous one? Isn't it call methode target?
It isn't very important, but I'll be glad any good answer. Thanks!
P.S. sorry for my English.
//EDITED: added this statement to all "name" references. Nothing changes.
When invoking the [[Call]] property, the behavior is different for
different types of closures. A closure is an object that contains a
reference to a method, and the [[Call]] property acts differently
depending on whether it is a function, method, or class closure. A
function closure is one that is of a global method that isn't
associated with any instance of a class. A method closure contains an
instance method of a class, and will always remember its original
"this" value.
If the closure is a function closure, then the first argument passed
to [[Call]] is passed on to the method and gets used as the "this"
value. If the first argument is null or undefined, then the global
object will be used as the "this" value for the method.
If the closure is a method closure, then the first argument of
[[Call]] will be ignored, and the saved "this" value for the method
closure will be passed to the method as the first argument. A method
closure records what its original "this" value was and always uses
that instead of the first argument to [[Call]].
If the closure is a class closure, and there is 1 argument passed to
[[Call]] (in addition to the "this" argument), then the call is
treated as a type conversion, and the argument will be coerced to the
type represented by the closure.
http://learn.adobe.com/wiki/display/AVM2/2.4+Method+invocation+notes
I am not sure if I am missing something here. I would like to compare two classes that uses the same interface. Is this possible? I understand that the is operator compares classes, but is there any similar function when you use interfaces?
// works
var effect1 : CrazyEffect = new CrazyEffect();
var effect2 : SaneEffect = new SaneEffect();
trace(effect1 is effect2) // false
// does not work
var effect1 : ISoundEffect = new CrazyEffect();
var effect2 : ISoundEffect = new SaneEffect();
trace(effect1 is effect2)
1067: Implicit coercion of a value of type ISoundEffect to an unrelated type Class.
Note the differences between concepts of a class and of an object. The former is a data type whereas the latter is a runtime instance of it, a variable. is operator can not compare one variable to another.
According to language reference
is Operator
Evaluates whether an object is compatible with a specific data type,
class, or interface. Use the is operator instead of the instanceof
operator for type comparisons. You can also use the is operator to
check whether an object implements an interface.
In other words, compiler expects the first operand to be a variable whereas the second operand should be a type identifier.
var sample:String = "Object is an instance of a class.";
^^^ ^^^
variable type identifier
However effect2 is not a type identifier but a variable. Hence the error message.
Unfortunately there is no generic operator to test for interface commonality. The only alternative is:
trace((s is ISoundEffect) && (t is ISoundEffect));
Update
Checking whether objects are instances of a same class can be done by comparing class names:
if (getQualifiedClassName(effect1) == getQualifiedClassName(effect2)) {
// true
}
For in depth discussion see Get the class used to create an object instance in AS3
Even though it will work with getQualifiedClassName, there's a better method to check whether two objects are instances of the same class:
a['constructor'] === b['constructor']
getQualifiedClassName is very slow and CPU intensive. Since the above code just compares property values it is lightning fast. And yes, constructor IS a property of every object, however FB will complain if you try to access it using dot-notation, that's why I use dynamic property access.