Как я могу создать новый экземпляр класса из класса внутри (статического) класса? - PullRequest
8 голосов
/ 14 июня 2010

Я новичок в Java (имею опыт работы с C #),

это то, что я хочу сделать:

public final class MyClass
{
    public class MyRelatedClass
    {
      ...
    }
}

public class OtherRandomClass
{
    public void DoStuff()
    {
       MyRelatedClass data = new MyClass.MyRelatedClass(); 
    }
}

, которая выдает эту ошибку в Eclipse:

Нет включающего экземпляра типа BitmapEffects.Необходимо квалифицировать выделение с включающим экземпляром типа BitmapEffects (например, xnnew A (), где x - это экземпляр BitmapEffects).

Это возможно в C # со статическими классами, как это должно быть сделано здесь?

Ответы [ 4 ]

19 голосов
/ 14 июня 2010

Как вы определили MyRelatedClass, вам нужно иметь экземпляр MyClass, чтобы иметь возможность получить доступ / создать экземпляр этого класса.

Обычно в Java этот шаблон используется, когда экземпляру MyRelatedClass требуется доступ к некоторым полям экземпляра MyClass (отсюда ссылки на «включающий экземпляр» в предупреждении компилятора).

Что-то вроде этого должно скомпилироваться:

public void doStuff() {
   MyClass mc = new MyClass();
   MyRelatedClass data = mc.new MyRelatedClass(); 
}

Однако, если экземпляру MyRelatedClass не требуется доступ к полям включающего его экземпляра (к полям MyClass), вам следует рассмотреть определение MyRelatedClass как статический класс, это позволит исходному коду, который вы опубликовали, скомпилировать.

Разница в наличии вложенного класса (того, что вы опубликовали) и статического вложенного класса (a static classв class) это то, что в первом случае вложенный класс принадлежит экземпляру родительского класса, в то время как последний не имеет такого отношения - только отношение логическое / пространство имен.

4 голосов
/ 14 июня 2010

Попробуйте определить MyRelatedClass как статический.

изменить
Подробнее по теме
http://java.sun.com/docs/books/tutorial/java/javaOO/nested.html

2 голосов
/ 14 июня 2010

В ответ на комментарии об упаковке нескольких классов в один файл: в отличие от .NET, большинство реализаций java обеспечивают строгую корреляцию между именем типа открытого класса и именем файла, в котором объявлен тип класса. Это нежесткое требование, но не используется система, в которой корреляция не обеспечивается.JLS - 7.6 Объявления типов верхнего уровня говорит следующее:

Когда пакеты хранятся в файловой системе (§7.2.1), хост-система может выбрать принудительное ограничениечто это ошибка времени компиляции, если тип не найден в файле с именем, состоящим из имени типа и расширения (например, .java или .jav), если выполняется одно из следующих условий:

  • На тип ссылается код в других единицах компиляции пакета, в котором объявлен тип.
  • Тип объявлен как открытый (и, следовательно, потенциально доступен из кода в других пакетах).

См. Этот вопрос SO: несколько объявлений классов в одном файле

Если вы хотите создать пространство имен для включения связанных классов, то используйтестатические внутренние классы - это то, что вам нужно.Статическое объявление не означает один экземпляр - они все еще могут быть созданы - static означает, что они могут быть созданы без ссылки на класс вложения.Поскольку включающий класс предназначен только для группировки, а не данных, вы можете сделать его статическим.Чтобы было яснее, что включающий класс предназначен только для группировки, вы должны объявить его как interface, чтобы его нельзя было создать и не иметь деталей реализации.

Хотя лично я бы воздержался от этого- в Java пакеты используются для реализации пространства имен.Использование внутренних классов для этого быстро становится громоздким.(Я пробовал это!)

0 голосов
/ 14 июня 2010

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

  1. делает вложенный класс статическим, как предлагает Мервин, или
  2. создайте его, используя экземпляр внешнего класса, как подсказывает сообщение об ошибке.

На практике я редко создаю экземпляр внутреннего класса, за исключением методов внешнего класса, и я редко делаю такие классы изменяемыми - но это только я.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...