Вы можете сделать это с помощью функции reshape()
или с функциями melt()
/ cast()
в пакете reshape. Для второго варианта пример кода:
library(reshape)
cast(dat1, name ~ numbers)
Или с помощью reshape2
library(reshape2)
dcast(dat1, name ~ numbers)
Внутренний класс - это просто способ четко отделить некоторые функциональные возможности, которые действительно относятся к исходному внешнему классу. Они предназначены для использования, если у вас есть 2 требования:
Учитывая эти требования, внутренние классы имеют полный доступ к своему внешнему классу. Поскольку они в основном являются членами внешнего класса, имеет смысл, что они имеют доступ к методам и атрибутам внешнего класса, включая рядовых.
Поскольку ваш метод main()
находится в классе ABC
, который может получить доступ к собственному внутреннему классу.
ABC
получить доступ к классам, вложенным в класс ABC
, но почему они могут обращаться к частным i> членам классов, вложенных в класс ABC
в Java.
– O. R. Mapper
16 December 2014 в 13:07
Логика внутренних классов заключается в том, что если вы создаете внутренний класс во внешнем классе, это потому, что им нужно будет поделиться несколькими вещами, и поэтому имеет смысл для них иметь больше гибкости, чем «регулярные», классы.
Если в вашем случае нет смысла, чтобы классы могли видеть внутреннюю работу друг друга, что в основном означает, что внутренний класс мог бы просто быть обычным классом, вы может объявить внутренний класс как static class XYZ
. Использование static
будет означать, что они не будут делить состояние (и, например, new ABC().new XYZ()
не будет работать, и вам нужно будет использовать new ABC.XYZ()
. Но если это так, вам следует подумать о том, следует ли XYZ
действительно, является внутренним классом, и, возможно, он заслуживает своего собственного файла. Иногда имеет смысл создавать статический внутренний класс (например, если вам нужен небольшой класс, который реализует интерфейс, используемый вашим внешним классом, и это не будет полезно в любом месте). Но примерно в половине случаев это должно было быть сделано внешним классом.
Тило добавил хороший ответ для вашего первого вопроса «Как это возможно?». Я хочу немного рассказать о втором заданном вопросе: почему это поведение разрешено?
Для начала давайте просто будем совершенно ясно, что это поведение допускается не только для внутренних классов, которые по определению не статичны вложенные типы. Такое поведение разрешено для всех вложенных типов, включая вложенные перечисления и интерфейсы, которые должны быть статическими и не могут иметь закрытый экземпляр. В принципе, модель упрощается до следующего утверждения: вложенный код имеет полный доступ к охватывающему код - и наоборот.
Итак, почему же? Я думаю, что пример лучше иллюстрирует точку.
Подумайте о своем теле и вашем мозгу. Если вы вводите героин в руку, ваш мозг становится высоким. Если регион миндалины вашего мозга видит то, что, по его мнению, угрожает вашей личной безопасности, скажем, например, оса, он заставит ваше тело повернуться в другую сторону и бежать за холмами, если вы «не подумаете» дважды об этом.
Итак, мозг является неотъемлемой частью тела - и, как ни странно, наоборот. Использование контроля доступа между такими тесно связанными объектами утрачивает свою претензию на отношения. Если вам нужен контроль доступа, вам нужно отделить классы больше от действительно разных единиц. До тех пор они являются одной и той же единицей. Примером вождения для дальнейших исследований было бы посмотреть, как обычно реализуется Java Iterator
.
Неограниченный доступ от включения кода во вложенный код делает его, по большей части , довольно бесполезно добавлять модификаторы доступа к полям и методам вложенного типа. Это добавляет беспорядок и может обеспечить ложное чувство безопасности для новых пользователей языка программирования Java.
Если вам нравится скрывать частных членов вашего внутреннего класса, вы можете определить интерфейс с публичными членами и создать анонимный внутренний класс, который реализует этот интерфейс. Пример ниже:
class ABC{
private interface MyInterface{
void printInt();
}
private static MyInterface mMember = new MyInterface(){
private int x=10;
public void printInt(){
System.out.println(String.valueOf(x));
}
};
public static void main(String... args){
System.out.println("Hello :: "+mMember.x); ///not allowed
mMember.printInt(); // allowed
}
}
x
является общедоступным, это запрещено, например mMember.x
.
– MAC
22 August 2018 в 18:48
Внутренний класс рассматривается как атрибут класса Outer. Следовательно, независимо от того, какая переменная экземпляра класса Inner является частной или нет, Outer-класс может получить доступ без каких-либо проблем, как доступ к другим его частным атрибутам (переменным).
class Outer{
private int a;
class Inner{
private int b=0;
}
void outMethod(){
a = new Inner().b;
}
}
Внутренний класс (для целей контроля доступа) считается частью содержащего класса. Это означает полный доступ ко всем частным лицам.
Способ реализации: использовать синтетические методы, защищенные пакетом. Внутренний класс будет скомпилирован в отдельный класс в одном пакете (ABC $ XYZ). JVM не поддерживает этот уровень изоляции напрямую, так что на уровне байт-кода ABC $ XYZ будут иметь защищенные пакетом методы, которые внешний класс использует для доступа к частным методам / полям.
Ограничения доступа выполняются для каждого класса. Невозможно, чтобы метод, объявленный в классе, не мог получить доступ ко всем членам экземпляра / класса. Разумеется, внутренние классы также имеют неограниченный доступ к членам внешнего класса, а внешний класс имеет неограниченный доступ к членам внутреннего класса.
Поместив класс внутри другого класса, вы делают его жестко привязанным к реализации, и все, что является частью реализации, должно иметь доступ к другим частям.