Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call a method created in an inline class [duplicate]

Tags:

java

I just came to know that there is a process called in-line class with the help of which I can create a new object and modify its class methods on the fly. I don't know if I can create new methods and variables inside the in-line class and use them. So I did this experiment. My IDE did not show any error while creating a new method inside the in-line class. Now I don't know how to access the newly created method. My doubt is, can I create a new method while creating an in-line class?(If yes then how?) Or, in-line class is only for overloading the existing methods?

public class Main {
public static void main(String[] args) {
    Animals cat = new Animals("Cat") {
        @Override
        public void makeNoise() {
            System.out.println("MEOW MEOW");
        }

        public void color() {
            System.out.println("Color is: white");
        }
    };
    cat.makeNoise();
    cat.color(); //this is showing error
    }
}

Animal class

class Animals {
private String name;

public Animals(String name) {
    this.name = name;
}

public void makeNoise() {
    System.out.println("Sound of the animal");
}
}
like image 887
Akash Nath Avatar asked Jan 25 '23 06:01

Akash Nath


1 Answers

The easiest change: use var:

public static void main(String[] args) {
    var cat = new Animals("Cat") {
        @Override
        public void makeNoise() {
            System.out.println("MEOW MEOW");
        }

        public void color() {
            System.out.println("Color is: white");
        }
    };
    cat.makeNoise();
    cat.color();
}

This now works, because cat isn't an Animals, it's inferred as a more specific type than that - it's a class that doesn't have an accessible name, so you can't write it as an explicit variable.


In fact, you were able to access anonymous class methods prior to the introduction of var, in a way:

    new Animals("Cat") {
        // ...

        public void color() { ... }
    }.color();

This worked prior to var, because the expression new Animals("Cat") { ... } has a more specific type that Animals. The problem is, you can only invoke those extra methods directly on the new instance creation expression, because you can only assign it to a variable of type Animals (or a superclass), thus preventing the compiler from accessing the specific class methods.


An alternative would be to declare it as a named class.

The most similar to what you have here would be a local class, although they are pretty rarely used (if known about at all), in my experience:

public static void main(String[] args) {
  class Cat extends Animals {
    Cat() { super("Cat"); }

    // ...

    public void color() { ... }
  }

  Cat cat = new Cat();
  cat.color();
}

This is sort-of what the var approach does; it just gives the type an explicit name. This approach would be good if you wanted to create more than one instance of Cat in that method.

But there's not an obvious reason why this would need to be a local class: you could alternatively declare it as a nested or inner class, or, of course, a top-level class.

like image 105
Andy Turner Avatar answered Jan 30 '23 00:01

Andy Turner