Анонимный класс java пример

Anonymous Inner Class in Java

Nested Classes in Java is prerequisite required before adhering forward to grasp about anonymous Inner class. It is an inner class without a name and for which only a single object is created. An anonymous inner class can be useful when making an instance of an object with certain “extras” such as overriding methods of a class or interface, without having to actually subclass a class.

Tip: Anonymous inner classes are useful in writing implementation classes for listener interfaces in graphics programming.

The syntax of an anonymous class expression is like the invocation of a constructor, except that there is a class definition contained in a block of code.

// Test can be interface,abstract/concrete class Test t = new Test() < // data members and methods public void test_method() < . . >>;

Now let us do discuss the difference between regular class(normal classes) and Anonymous Inner class

  • A normal class can implement any number of interfaces but the anonymous inner class can implement only one interface at a time.
  • A regular class can extend a class and implement any number of interfaces simultaneously. But anonymous Inner class can extend a class or can implement an interface but not both at a time.
  • For regular/normal class, we can write any number of constructors but we can’t write any constructor for anonymous Inner class because the anonymous class does not have any name and while defining constructor class name and constructor name must be same.

Accessing Local Variables of the Enclosing Scope, and Declaring and Accessing Members of the Anonymous Class

Читайте также:  Калькулятор питон в консоли

Like local classes, anonymous classes can capture variables; they have the same access to local variables of the enclosing scope:

  • An anonymous class has access to the members of its enclosing class.
  • An anonymous class cannot access local variables in its enclosing scope that are not declared as final or effectively final.
  • Like a nested class, a declaration of a type (such as a variable) in anonymous class shadows any other declarations in the enclosing scope that have the same name.

Anonymous classes also have the same restrictions as local classes with respect to their members:

  • We cannot declare static initializers or member interfaces in an anonymous class.
  • An anonymous class can have static members provided that they are constant variables.
  • Fields
  • Extra methods (even if they do not implement any methods of the supertype)
  • Instance initializers
  • Local classes

Anonymous inner classes are generic created via below listed two ways as follows:

Now let us take an example with which we will understand anonymous inner class, let us take a simple program

Источник

Анонимный класс java пример

У меня в идее все декларирует(компиляторо не ругается) я декларировал и переменные статические и создавал статические методы, другой вопрос что статику из анонимного класса не достать. Почему автор так написал? Может я что то не так понял? Есть ответы: Внутренний анонимный класс может содержать статические переменные и методы c версии Java 16! Статические методы или переменные достать можно, просто нужно обратиться к ним в main методе внутри воложеного класса: System.out.println(staticInt); Иначе как сделать извлечение статик элементов из анонимного класса я не придумал.

Предыдущая статья про нестатические вложенные классы (1/3 часть): https://javarush.com/groups/posts/2181-vlozhennihe-vnutrennie-klassih Продолжение про статические вложенные классы (3/3 часть): https://javarush.com/groups/posts/2183-staticheskie-vlozhennihe-klassih

вот кое что не понятно. Тут написано: «Если каждому из наших анонимных классов-модулей понадобится какое-то отличающееся поведение, свои специфические методы, которых нет у других, мы легко можем дописать их:»

 MonitoringSystem generalModule = new MonitoringSystem() < @Override public void startMonitoring() < System.out.println("Мониторинг общих показателей стартовал!"); >public void someSpecificMethod() < System.out.println("Специфический метод только для первого модуля"); >>; 

Вопрос. А имеет смысл такие методы вообще писать (даже если пропустит компилятор)? будет ли вообще хоть какая-нибудь возможность достучаться до специфического метода? Ведь данный метод существует лишь в анонимном классе, имя которого нам не известно. Объект анонимного класса хранится в переменной типа интерфейса. Данному интерфейсу ничего не известно о данном методе (который есть только у наследника — в анонимном классе). И компилятор по этой причине не позволит к нему обратиться. Более того, мы не сможем создать ссылочную переменную типа анонимного класса и перекинуть туда объект, чтобы вызвать данный метод — по причине того, что нам банально не известно имя анонимного класса, чтобы создать ссылочную переменную данного типа. Я прав?

Супер лекция. Еще бы компоновали ссылки в конце по смежным темам(здесь например по всем типам вложенных классов). А то искать через поисковик неудобно. Или я чего-то не догоняю.

 import java.util.Scanner; interface Eatable < public void eat(); >public class Test < public static final Scanner menu = new Scanner(System.in); public static final String whatWouldULikeToEat = menu.nextLine(); public static void main(String[] args) < Eatable eatable = new Eatable() < @Override public void eat() < System.out.printf("Well, I would like to eat %s, please.", whatWouldULikeToEat); >public String receipt() < return whatWouldULikeToEat; >>; eatable.eat(); System.out.println("\nOkay, sir."); > > 

Важный момент в том, что дополнительные методы, помимо тех, что мы переопределяем, нельзя использовать извне этого анонимного класса, а только внутри него. Т.е. в примере:

 MonitoringSystem generalModule = new MonitoringSystem() < @Override public void startMonitoring() < System.out.println("Мониторинг общих показателей стартовал!"); >public void someSpecificMethod() < System.out.println("Специфический метод только для первого модуля"); >>; 

Источник

Внутренние анонимные классы

Внутренние анонимные классы, примеры - 1

— Так, не спорь с тетей. В 31 веке принято здороваться опять, если не видел человека более получаса. Так что не возникай!

Так вот, новая интересная тема – размножение роботов!

— Шучу, новая тема – анонимные вложенные классы.

Иногда в Java встречается ситуация, когда нужно унаследовать класс от нескольких классов. Т.к. множественное наследование классов в Java запрещено, эту проблему решают с помощью внутренних классов: в нужном нам классе мы объявляем внутренний класс и наследуем его от требуемого класса. Пример:

class Tiger extends Cat < public void tigerRun() < . >public void startTiger() < TigerThread thread = new TigerThread(); thread.start(); > class TigerThread extends Thread < public void run() < tigerRun(); > > >

Давай разберем этот пример:

Нам нужен класс, унаследованный от Thread, чтобы переопределить у него метод run.

Для этого внутри класса Tiger мы объявили внутренней класс TigerThread, который унаследовали от Thread и у которого переопределили метод run.

Для нашего удобства в классе Tiger мы объявили два метода (аналоги методов run и start класса Thread) –методы tigerRun и startTiger.

В методе startTiger мы создаем объект типа TigerThread и вызываем у него метод start().

При этом Java-машина создаст новую нить, и эта нить начнет работу с вызова метода run, класса TigerThread.

А этот метод в свою очередь вызовет наш метод run – метод tigerRun.

— С нитями я уже дело имел, так что вроде не очень сложно.

А обязательно называть методы tigerRun и startTiger?

— Нет, можно было назвать run и start, но я хотела дополнительно показать, что мы не наследуемся от Thread, к тому же ты мог сильнее запутаться в моем пояснении.

— Ок. Тогда все вроде понятно. Только при вызове метода startTiger второй раз мы создадим еще один класс Thread и запустим его. Не получится ли что у нас «один тигр будет бегать в двух различных нитях»?

— Ну ты и глазастый. Согласна, это не хорошо. Тогда давай перепишем код так:

class Tiger extends Cat < public void tigerRun() < . >public void startTiger() < thread.start(); >private TigerThread thread = new TigerThread(); private class TigerThread extends Thread < public void run() < tigerRun(); > > >

— Не то, чтобы отлично. Два раза все равно вызывать такой метод нельзя. Но в этот раз мы хотя бы не будем создавать вторую нить и делать вид, что все хорошо.

— Правильно, запустил второй раз, тигра – получи Exception.

— Я уже лучше тебя вижу все ошибки, Элли!

Да, ты молодец. Тогда перейдём к анонимным внутренним классам.

Обрати внимание на несколько аспектов вышеописанного кода:

1) Мы унаследовались от класса Thread, но фактически не дописали туда никакого кода. Нам скорее пришлось унаследоваться, а не «мы унаследовались с целью расширить класс Thread»

2) Будет создан всего один объект класса TigerThread.

Т.е. с целью переопределить один метод и создать один объект, мы написали целую кучу кода.

Помнишь, как я рассказывала про появление конструкторов?

TigerThread thread = new TigerThread(); private class TigerThread extends Thread < public void run() < tigerRun(); > >
Thread thread = new Thread() < public void run() < tigerRun(); > >;

— Вижу, что код стал компактнее, но не совсем понимаю, что произошло.

— Мы можем объединить в одном месте четыре вещи:

1) объявление класса-наследника

4) создание объекта класса-наследника.

Фактически мы объединяем вместе две операции – объявление класса-наследника и создание его объекта:

Cat tiger = new Tiger(); class Tiger extends Cat

Еще раз разбираем синтаксис:

Thread thread = new Thread();
Thread thread = new Thread() < >;

Обрати внимание – мы не просто объявляем новый класс – мы создаем переменную – в конце ставится точка с запятой!

— А если мы хотим переопределить метод run, то нужно писать так:

Thread thread = new Thread() < public void run() < System.out.println("new run-method"); >>;

— Быстро схватываешь – молодец!

— Спасибо. А если мне нужны еще методы, которых нет у класса Thread?

Это же полноценный внутренний класс, хоть и анонимный:

Thread thread = new Thread()  < public void run() < printHi(); >public void printHi() < System.out.println("Hi!"); >>; 

Зеленым – создания объекта.

— Полноценный внутренний класс?

Т.е. я могу и переменные внешнего класса использовать?

— А в конструктор я могу что-то передавать?

— Да, но только параметры конструктора базового класса:

Мы не можем добавить свои параметры в чужой конструктор. Зато можем использовать переменные внешнего класса – это достаточно сильно компенсирует этот недостаток.

— А если мне все-таки очень нужно добавить в конструктор еще параметры?

— Тогда объяви обычный не анонимный внутренний класс и используй его.

— Действительно, я чуть не забыл об этом.

А если я объявлю статическую переменную, тогда анонимный класс будет вложенным, а не внутренним — т.е. без ссылки на внешний класс?

— Нет. Будет именно анонимный внутренний класс. Смотри примеры:

Thread thread = new Thread() < public void run() < tigerRun(); > >;
TigerThread thread = new TigerThread(); private class TigerThread extends Thread < public void run() < tigerRun(); > >
static Thread thread = new Thread() < public void run() < tigerRun(); > >;
static TigerThread thread = new TigerThread(); private class TigerThread extends Thread < public void run() < tigerRun(); > >

— Ясно. Статической становится только переменная, но не класс.

На самом деле, в процессе компиляции Компилятор создает внутренние классы для всех анонимных внутренних классов. Такие классы обычно получают имена «1», «2», «3», и т.д.

Источник

Оцените статью