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
  • 712
  • 1
  • 11
  • 27

4 Answers4

4

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

pbaris
  • 4,525
  • 5
  • 37
  • 61
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
  • 6,868
  • 4
  • 27
  • 41
  • 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,435
  • 3
  • 14
  • 44
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
  • 73
  • 7