Использование классов внутри других классов
Бывает такое, что мы хотели бы использовать методы одного класса внутри другого, но не хотели бы наследовать от этого класса.
Почему мы не хотим наследовать?
Во-первых, используемый класс может являться вспомогательным и по логике нашего кода может не подходить на роль родителя.
Во-вторых, мы можем захотеть использовать несколько классов внутри другого класса, а с наследованием это не получится, ведь в PHP у класса может быть только один родитель.
Давайте посмотрим на практическом примере. Пусть у нас дан следующий класс Arr , в объект которого мы можем добавлять числа с помощью метода add :
Давайте теперь добавим в наш класс метод, который будет находить сумму квадратов элементов и прибавлять к ней сумму кубов элементов.
Пусть у нас уже существует класс SumHelper , имеющий методы для нахождения сумм элементов массивов:
Логично будет не реализовывать нужные нам методы еще раз в классе Arr , а воспользоваться методами класса SumHelper внутри класса Arr .
Для этого в классе Arr внутри конструктора создадим объект класса SumHelper и запишем его в свойство sumHelper :
Теперь внутри Arr доступно свойство $this->sumHelper , в котором хранится объект класса SumHelper с его публичными методами и свойствами (если бы публичные свойства были, сейчас их там нет, только публичные методы).
Создадим теперь в классе Arr метод getSum23 , который будет находить сумму квадратов элементов и прибавлять к ней сумму кубов элементов, используя методы класса SumHelper :
sumHelper = new SumHelper; > // Находим сумму квадратов и кубов элементов массива: public function getSum23() < // Для краткости запишем $this->nums в переменную: $nums = $this->nums; // Найдем описанную сумму: return $this->sumHelper->getSum2($nums) + $this->sumHelper->getSum3($nums); > public function add($number) < $this->nums[] = $number; > > ?>?php>
Давайте воспользуемся созданным классом Arr :
add(1); // добавляем в массив число 1 $arr->add(2); // добавляем в массив число 2 $arr->add(3); // добавляем в массив число 3 // Находим сумму квадратов и кубов: echo $arr->getSum23(); ?>?php>
Самостоятельно повторите описанные мною классы Arr и SumHelper .
Создайте класс AvgHelper с методом getAvg , который параметром будет принимать массив и возвращать среднее арифметическое этого массива (сумма элементов делить на количество).
Добавьте в класс AvgHelper еще и метод getMeanSquare , который параметром будет принимать массив и возвращать среднее квадратичное этого массива (квадратный корень, извлеченный из суммы квадратов элементов, деленной на количество).
Добавьте в класс Arr метод getAvgMeanSum , который будет находить сумму среднего арифметического и среднего квадратичного из массива $this->nums .
Объявления вложенных классов
Класс можно объявить в области другого класса. Такой класс называется вложенным классом. Вложенные классы считаются в пределах область включаемого класса и доступны для использования в рамках этого область. Для обращения ко вложенному классу из области, отличной от непосредственно включающей его области, следует использовать полное имя.
В следующем примере показано, как объявить вложенные классы.
// nested_class_declarations.cpp class BufferedIO < public: enum IOError < None, Access, General >; // Declare nested class BufferedInput. class BufferedInput < public: int read(); int good() < return _inputerror == None; >private: IOError _inputerror; >; // Declare nested class BufferedOutput. class BufferedOutput < // Member list >; >; int main()
BufferedIO::BufferedInput и BufferedIO::BufferedOutput объявляются в BufferedIO пределах . Эти имена классов не видимы за пределами области класса BufferedIO . Однако объект типа BufferedIO не содержит объекты типа BufferedInput или BufferedOutput .
Вложенные классы могут непосредственно использовать имена, имена типов, имена статических членов и перечислители только из включающего класса. Для использования имен других членов класса необходимо использовать указатели, ссылки или имена объектов.
В предыдущем примере BufferedIO к перечислению IOError можно получить доступ непосредственно с помощью функций-членов во вложенных классах BufferedIO::BufferedInput или BufferedIO::BufferedOutput , как показано в функции good .
Вложенные классы объявляют только типы в пределах области класса. Они не создают объекты по вложенном классе. В предыдущем примере объявляется два вложенных класса, но не объявляются объекты этих типов классов.
Исключением из видимости области объявления вложенного класса является объявление имени типа вместе с опережающим объявлением. В этом случае имя класса, объявленное с помощью опережающего объявления, видимо за пределами включающего класса, при этом область определена как наименьшая включающая область вне класса. Например:
// nested_class_declarations_2.cpp class C < public: typedef class U u_t; // class U visible outside class C scope typedef class V <>v_t; // class V not visible outside class C >; int main() < // okay, forward declaration used above so file scope is used U* pu; // error, type name only exists in class C scope u_t* pu2; // C2065 // error, class defined above so class C scope V* pv; // C2065 // okay, fully qualified name C::V* pv2; >
Права доступа во вложенных классах
Вложение класса в другой класс не предоставляет особые права доступа к функциям-членам вложенного класса. Аналогичным образом, функции-члены включающего класса не имеют особых прав доступа к членам вложенного класса.
Функции-члены во вложенных классах
Функции-члены, объявленные во вложенных классах, могут быть определены в области файла. Предыдущий пример можно было бы записать следующим образом:
// member_functions_in_nested_classes.cpp class BufferedIO < public: enum IOError < None, Access, General >; class BufferedInput < public: int read(); // Declare but do not define member int good(); // functions read and good. private: IOError _inputerror; >; class BufferedOutput < // Member list. >; >; // Define member functions read and good in // file scope. int BufferedIO::BufferedInput::read() < return(1); >int BufferedIO::BufferedInput::good() < return _inputerror == None; >int main()
В предыдущем примере синтаксис с полным именем типа используется для объявления имени функции. Объявление:
BufferedIO::BufferedInput::read()
означает » read функция, являющаяся членом BufferedInput класса, который находится в область BufferedIO класса». Так как в этом объявлении используется синтаксис имени квалифицированного типа, возможны конструкции следующей формы:
typedef BufferedIO::BufferedInput BIO_INPUT; int BIO_INPUT::read()
Предыдущее объявление эквивалентно предыдущему, но вместо имен классов используется typedef имя.
Дружественные функции во вложенных классах
Считается, что дружественные функции, объявленные во вложенном классе, находятся в области вложенного, а не включающего класса. Поэтому дружественные функции не получают особых прав доступа к членам или функциям-членам включающего класса. Если требуется использовать имя, объявленное во вложенном классе, в дружественной функции, и дружественная функция определена в области видимости файла, используйте полные имена типов, как показано ниже.
// friend_functions_and_nested_classes.cpp #include enum < sizeOfMessage = 255 >; char *rgszMessage[sizeOfMessage]; class BufferedIO < public: class BufferedInput < public: friend int GetExtendedErrorStatus(); static char *message; static int messageSize; int iMsgNo; >; >; char *BufferedIO::BufferedInput::message; int BufferedIO::BufferedInput::messageSize; int GetExtendedErrorStatus() < int iMsgNo = 1; // assign arbitrary value as message number strcpy_s( BufferedIO::BufferedInput::message, BufferedIO::BufferedInput::messageSize, rgszMessage[iMsgNo] ); return iMsgNo; >int main()
В следующем коде показана функция GetExtendedErrorStatus , объявленная в качестве дружественной функции. В функции, определенной в области видимости файла, сообщение копируется из статического массива в член класса. Обратите внимание, что для оптимальной реализации функции GetExtendedErrorStatus рекомендуется объявить ее следующим образом.
int GetExtendedErrorStatus( char *message )
В предыдущем интерфейсе несколько классов могут использовать службы этой функции, передав адрес памяти, в которую требуется скопировать сообщение об ошибке.
Как использовать метод класса в другом классе python?
Для этого нужно указать этот класс в качестве родителя по отношению к текущему классу. Например, если в нашем классе MyClass мы хотим использовать метод method класса Parent :
class MyClass(Parent): # наследуем от класса Parent pass MyClass.method # # метод method родительского класса доступен для использования
Как использовать переменную из другого класса java
Если переменная объявлена public , то мы можем получить к ней доступ напрямую, указав имя через точку после имени объекта класса.
Если переменная объявлена private , то необходимо вызвать геттер этой переменной.
class Friend public String name; private String mail; public Friend(String name, String mail) this.name = name; this.mail = mail; > public String getMail() return mail; > > public class App public static void main(String[] args) Friend friend = new Friend("Ivan", "Ivan@mail.ru"); System.out.println(friend.name); // => Ivan System.out.println(friend.getMail()); // => Ivan@mail.ru > >
