1

I create an interface as follow :

// The OnClickListener interface :
public interface OnClickListener{

    void onClick(); 

}

And a I create a Person Class :

// Class Person :
public class Person
{
    String name;

    OnClickListener onClicklisner;

    Person(String name) 
    {   
        this.name = name;

        this.onClickListener = new OnClickListener() 
        {      
           @Override
            public void onClick() {

                //I want to access to this.name attribute, but it doesn't work :
                System.out.println(this.name);
            }
        };
    }
}

In the onClick() method above, I want to access to this.name attribute, but it doesn't work.

How I can access that ?

Thank you very much.

totoaussi
  • 683
  • 1
  • 8
  • 23

4 Answers4

4

You should prefix it with the class name Person.this.name

pbaris
  • 4,305
  • 4
  • 38
  • 60
2
//I want to access to this.name attribute, but it doesn't work :
  System.out.println(this.name);

here this refers to OnClickListener object which doesn't have name

Use name instead of this.name as below,

this.onClicklisner = new OnClickListener()
{
    @Override
    public void onClick() {

        //I want to access to this.name attribute, but it doesn't work :
        System.out.println(name);
    }
};
Vikas Yadav
  • 6,200
  • 2
  • 23
  • 36
  • This is good, but if the `name` field changes, it won't work. You should either declare the field as final, or rename the parameter `name` to `nom` or something, I think – user May 14 '20 at 15:39
2

pbaris's approach of Person.this.name works, but you can also make a getter and use getName() or, if you declare the field name final, you can use name directly without a prefix.

You can also use a lambda expression, since your interface is a functional interface

this.onClickListener = () -> System.out.println(this.name);
user
  • 7,154
  • 3
  • 11
  • 41
1

You have fallen into a common scope trap in Java, and this approach defeats the purpose of interfaces. On the following line of code you instantiate an anonymous class:

this.onClickListener = new OnClickListener() {
// We are now in the scope of the anonymous class implementing the OnClickListener interface.
}

As pbaris's answer suggests, you could use Person.this.name to reference the parent object's attributes, but that couples your code to the Person class and defeats the purpose of having a separate class implement the OnClickListener interface. You could either have the Person class implement the interface, or declare a new class that implements the interface and takes a reference to Person as a constructor argument:

public class  PersonClickedListener implements OnClickListener {

    private Person parent;    

    public PersonClickedListener(Person parent) {
        this.parent = parent;
    }

    @Override
    public void onClick() {
        System.out.println(parent.name);
    }
}

Then, in Person:

public class Person
{
    String name;

    OnClickListener onClicklistener;

    Person(String name) 
    {   
        this.name = name;

        this.onClickListener = new PersonClickedListener();
    }
}

You could get even fancier and have Person implement an interface that exposes a getName() method, that way your PersonClickedListener could work for any class that implements that new interface.

wilsontfwi
  • 53
  • 5