This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Java this.method() vs method()
I've been reading some things and doing some tutorials about android java but I still dont understand what "this" means, like in the following code.
View continueButton = this.findViewById(R.id.continue_button);
continueButton.setOnClickListener(this);
View newButton = this.findViewById(R.id.new_button);
newButton.setOnClickListener(this);
Also why is it in this example that a button is not defined with Button but with View, what is the difference?
ps. Great site!! trying to learn java and got ALLOT of answers by searching here!
The this keyword is a reference to the current object. It is used to pass this instance of the object, and more.
For example, these two allocations are equal:
class Test{
int a;
public Test(){
a = 5;
this.a = 5;
}
}
Sometimes you have a hidden field you want to access:
class Test{
int a;
public Test(int a){
this.a = a;
}
}
Here you assigned the field a with the value in the parameter a.
The this keyword works the same way with methods. Again, these two are the same:
this.findViewById(R.id.myid);
findViewById(R.id.myid);
Finally, say you have a class MyObject that has a method which takes a MyObject parameter:
class MyObject{
public static void myMethod(MyObject object){
//Do something
}
public MyObject(){
myMethod(this);
}
}
In this last example you passed a reference of the current object to a static method.
Also why is it in this example that a button is not defined with Button but with View, what is the difference?
In Android SDK, a Button is a subclass of View. You can request the Button as a View and cast the View to a Button:
Button newButton = (Button) this.findViewById(R.id.new_button);
this is referring to the instance of the object that is being acted upon.
In the case that you have above, this.findViewById(R.id.continue_button) this is referring to a method in a parent class (Specifically either Activity.findViewById() or View.findViewByid(), assuming you are writing your own subclass of Activity or View!).
this refers to the current instance of a class
this in Java is a reference to the current object instance. So if you are writing a method for class MyClass, this is the current instance of MyClass.
Note that in your case, writing this.findViewById(...) isn't really necessary, and may be considered bad style.
"this" in object oriented languages such as java, c# is a reference to the object on which you are invoking the method or whose data you are accessing.
See if this link is helpful for you in understanding the "this" more -
http://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html
"this" is the current object instance.
class Blaa
{
int bar=0;
public Blaa()
{}
public void mogrify(int bar,Blaa that)
{
bar=1; //changes the local variable bar
this.bar=1; //changes the member variable bar.
that.bar=1; //changes "that"'s member variable bar.
}
}
Related
In Java as in PHP, instance fields declared in parent classes are inherited in child classes. Therefore, it is possible to access them using the keyword this (resp. $this in PHP).
In Java, if the child class happens to declare a field with the same name as the parent class, the parent class's field is hidden (see JLS 8.3.1.1-3: Hiding of Instance Variables). It is there, but if the child class wants to access it, it needs to use the keyword super, as in the following example:
class Foo {
protected int x = 1;
}
class Bar extends Foo {
protected int x = 2;
void somemethod() {
System.out.println(this.x); // prints 2
System.out.println(super.x); // prints 1
}
}
Please note that I consider hiding fields as a bad practice, as it only makes for confusing code and easily leads to logic bugs. It is best not to declare instance fields with the same name as an instance field of a parent class. Therefore, this question is of a purely academic nature.
Nevertheless I am curious: Is it in principle possible to access hidden instance fields in PHP, as is possible in Java? Would it be possible to translate the above code snippet to PHP?
<?php
class Foo {
protected $x = 1;
}
class Bar extends Foo {
protected $x = 2;
function somemethod() {
echo $this->x, PHP_EOL; // prints 2
//echo $parent->x, PHP_EOL; // doesn't compile... is there a way to do it?
}
}
Please note that I am talking about instance variables here. Class (i.e., static) variables are a different story altogether and are not a subject of this question.
If it is not possible: Does this mean that the parent instance field effectively gets overwritten in PHP (instead of just hidden), and is thus inaccessible?
The reason why this is not working for you, is because you are overriding the parent. Foo->$x is available in the child scope, therefor when you define X as 2 in Bar it overrides the previous set variable.
If you want something like this to work like in Java, then you would have to use constants.
class Foo {
const x = 1;
}
class Bar extends Foo {
const x = 2;
function somemethod() {
echo parent::x; // prints 1
echo self::x; // prints 2
}
}
Or you could simply change the variable name in Bar and then you would have direct access to it through inheritance.
I have a very weird situation. I have a class that has a couple of members, like this:
public class myMainClass
{
public aClass myObject = new aClass();
private int numberOfUpdates = 0;
public anotheClass.memberClass anotherObject = new anotheClass.memberClass();
Note that the anotherClass has a class defined within it. (Not sure if that enters into the problem I'm having).
Both aClass and anotheClass.memberClass have a member with the same name, ThisMember.
I also have a method within myMainClass that does some modifications to the members of the myMainClass object:
public void Update(double aPassedInNumber)
{
anotherObject.ThisMember = aPassedInNumber;
//etc
}
I'm only modifying that one member. However, when I do that, myObject.ThisMember also gets modified to the same value! It's as though (??) both member variables occupy the same location in memory. Or that one is somehow a reference to the other.
It's as if I had done:
public void Update(double aPassedInNumber)
{
anotherObject.ThisMember = aPassedInNumber;
myObject = aPassedInNumber;
//etc
}
BUT I'M NOT. I'm only doing the first assignment, yet both of those variables get modified.
I've traced this and printed out diagnostics and used a watch window and it clearly modifies both variables.
How can that be? What am I doing wrong? How can I fix it?
Oh, man. It looks like I still don't have a handle on the reference concept in JAVA. That one variable is indeed simply a reference to the other object.
Now it seems I have to implement a copy method for the class.
Aaaargh!!
===================================================================================================
UPDATE:
My problem was that I did not know that classes can indeed communicate with each other. For example, you can create 2 classes, instantiate an object of each class in your program, and then actually pass one object into the other. This not only directly solved my problem, it opens an entire world of possibilities for the future.
public class FirstClass {
int valueToPass = 100;
void methodToPass(){
//do stuff
return;
}
}
public class SecondClass {
FirstClass passedInObject;
int valueFromOtherClass = passedObject.valueToPass;
return;
}
}
===================================================================================================
I understand a class is a blueprint of attributes and actions that can be instantiated as an object.
I understand an inner class is a non static class defined within another class and has access to the outer class' data.
I understand a child class is a separate file defining a class that does not have access to its parent's data.
So I've got my main activity class of an Android application. I'm just making a simple dice game to help tie up all the loose ends. I've defined the follow child classes in separate .java files:
Dice
ScoreCard
I instantiate an array of 5 Dice objects and 1 ScoreCard object and attach those objects to a "view" in the android OS's window, then assign an action method to that view with the set click listener method inside the object. The objects work flawlessly. I can click the dice and they will hold and unhold themselves, roll, and update their own views. I can of course access the value of the dice from my main class by referencing their object.value variable. (I understand that accessors are presumed by many to be superior to directly interacting directly with a child class' variables, this app is just to solidify conceptual ideas of the overall flow of an application) I can click a slot on the scoresheet and it will toggle the highlight that slot as the slot to assign the score to. The scorecard object also updates the entire scorecard on the screen after each interaction.
So far so good, everything is working great, and I understand everything that is going on.
However, in my main activity class, I now want to create a roll function, and assign that function to the click listener for the roll button. That works, however, when assigning a function to the click listener, you can not reference any non final variables because the click listener of a given view actually instantiates an anonymous object (anonymous class?) of the View class and overrides the onclick method with its own, therefore you can not reference any non final variables from an inner class defined in another method. In other words, you can't pass the function you assign to the click listener any values from your main class, and although I do not understand why, the roll function I created can not access the main class' variables directly.
There is the first gap in my knowledge, and I've read dozens of tutorials, watched dozen's of videos, but I don't know why my roll function can't see the variables.
public mainclass extends otherclass {
#override
otherclass.method {
// where my application starts
int a=7;
roll();
}
void roll(){
int funcVar = a;
return;
{
}
Eclipse says that a can not be resolved.
I try to make a public thinking that might allow the function to see it, but if I change
int a=7;
to
public int a=7;
then Eclipse says that it can't be public, only final.
A way around this is to create a new child class called Roll, or perhaps ActionButton to use it for other buttons in the future, just as I did with the ScoreCard and Dice classes. This works great, in so far as I can instantiate a roll button object, assign a view to the object and then set the click listener to one of the object's methods. However, this transfers the functionality of my rollbutton from my MainActivity class to my RollButton class, which doesn't have access to the data in my dice and scorecard objects. In other words, I can't figure out how to make my child classes talk to each other, I don't really think they are even supposed to. I imagine the main class is supposed to access each child class independently, but if that's the case then I'm not really sure what I'm supposed to do at this point.
The only solution I can think of is to put all those child classes into the same child class, DiceGame, and pretty much just use the MainActivity class to instantiate an object of the DiceGame class and transfer processing entirely over to that object. While that would work, all the methods in the class would have access to all the data in the class, it seems to contradict the entire purpose of object oriented programming.
Is this all so messed up because of the way the click listener in android apps is assigned through instantiating an anonymous inner class that can't access any non final variables, or I just missing a key concept in the way Java applications are structured?
I'm sorry this is so long, but I really couldn't shorten it and still convey the entire problem.
-------edit----------
public class MainActivity extends Activity {
public int a=7;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
// my application starts here
Dice[] gameDice = new Dice[6];
for (int i=1;i<6;i++) gameDice[i]= new Dice();
for (int i = 1; i<6 ; i++){
gameDice[i].dieView = (ImageView) findViewById(R.id.die1 + (i-1));
gameDice[i].setListener();
}
int[] slotId = new int[] {R.id.val1,
R.id.val1,R.id.val2,R.id.val3,R.id.val4,R.id.val5,
R.id.val6,R.id.valsubtotal,R.id.valbonus,
R.id.val3k,R.id.val4k,R.id.val5k,R.id.valfh,
R.id.valsmstr,R.id.valstr,R.id.valdicey,R.id.valtotal
};
ScoreCard scoreCard = new ScoreCard();
scoreCard.NUMBER_OF_SLOTS = slotId.length;
for (int i=1 ; i<scoreCard.NUMBER_OF_SLOTS ; i++){
scoreCard.slotView[i]=(TextView) findViewById(slotId[i]);
if (i!=8 && i!=15) scoreCard.setListener(i);
}
scoreCard.initScoreCard();
rollButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
roll();
}
});
}// end of overridden method
void roll(){
//do stuff
int funcVar = a; // can totally see a now that it is higher scope
return;
}
}//end of class
The suggestion to increase the scope of a did in fact work. However, a is just an example I was using for simplicity's sake. I really need to access those data contained in the objects I instantiated, and if I instantiate them in a higher scope the application abruptly ends upon launch.
Perhaps the confusion is between a variable and a field. A field is a property that is associated with an object. A variable exists only in the context of a method. When the method finishes, the variable vanishes.
A field, on the other hand, looks exactly the same as a variable except that a field is declared outside of any method, directly on the class "body". Fields and methods are declared at the same hierarchical level. You can see that on Eclipse. Check the "outline" view.
If you need several methods to read and write the same "variable", then what you need is a field. I hope this clarifies.
Variables can have different scopes:
public class MyClass {
static int a; // variable bound to class MyClass, seen from all instances
int b; // variable bound to instance, each instance of MyClass has its own value
public void foo(int c) { // parameter variable: local
int d; // local variable
}
}
Local variables in a method are visible only within the same method invocation (so each time foo() is invoked, new local variables are used).
Values can be passed indirectly by storing them in instance or class variables (global variables), but that's ugly and error prone. The better variant is to pass the values as method arguments, this works well with multiple invocations and also multiple Threads, and removes the side effects you'd have when passing values using global variables.
In your example, just pass the value of a to your method:
public mainclass extends otherclass {
#override
otherclass.method {
// where my application starts
int a=7;
roll(a);
}
void roll(int funcVar){
// funcVar is whatever value was passed, here: 7
return;
{
}
This question already has answers here:
What does "this" point to?
(5 answers)
Closed 4 years ago.
public class CommandForm extends Form implements CommandListener {
Display d;
public CommandForm(String msg) {
super(msg);
this.addCommand(exit);
}
private void showMessage(String title, String text) {
Alert a = new Alert(title, text, null, AlertType.INFO);
d.setCurrent(a, this);
}
public void prepare_view(Display d){
this.setCommandListener(this);
this.d = d;
}
public void show_view(){
d.setCurrent(this);
}
}
I do not know exactly what the 'this' keyword means in this example. My lecturer says it is the current object, when I inquire further, he said it is the CommandForm. Is that correct? When you pass in 'this' into a parenthesis, e.g setCommandListener(this) are you actually passing the CommandForm? The only way I know how to use 'this' is like this way, this.d = d. So this is kinda new to me.
He's right. If you call setCommandListener(this) you are passing a reference to the current object into the method. When you do this.d = d you are setting the variable d which is part of the class (i.e this) to the incoming value (in parenthesis).
Your lecturer is indeed correct. It's the current object, and this is simply a means to refer to the object currently in scope.
You use the keyword to pass the reference to other objects e.g. object.doSomethingWith(this), and/or resolve ambiguity between members and variables (e.g. this.x = x - there are two different xs here).
Check out the Java Language Specification section on 'this'.
Yes, the this keyword is a reference to that particular instance of the CommandForm class.
Trying to understand upcasting in Java. Recently observed strange behavior.
Example:
public class A extends B {
public int i = 2;
public void printI() {
System.out.println("print i = " + this.i);
}
public static void main(String[] args) {
B a = new A(); // <- upcasting here
System.out.println("i = " + a.i);
a.printI();
}
}
class B {
public int i = 1;
public void printI() {}
}
//Output:
//i = 1
//print i = 2
Seems, that upcasted object has two separate "i" properties. One "i" accessible directly (a.i) and the other through methods of child class (a.printI()).
Looks like upcasted object gets properties from superclass and methods from child class.
How object can have two separate "i"s?!
Seems, that upcasted object has two separate "i" properties.
Firstly, it's worth being clear about terminology. There's no such thing as an "upcasted object" - and "i" is a field in each of A and B.
But yes, there are two separate fields here. It's not like one field "overrides" another or anything like that.
It's not clear what you were trying to achieve, but the declaration of i in A shadows the declaration of i in B. See section 6.4 of the Java Language Specification for more information.
Note that in almost all cases, fields should be private - at which point the hiding really doesn't matter, as you wouldn't try to refer to a variable which wasn't declared in the class you're coding in anyway.
That's how Java works. You have both fields "available", they just happen to have the same name. When you reference from the subclass, it is hiding the superclass' version, but it is still there.