Как использовать один класс в другом с
Перейти к содержимому

Как использовать один класс в другом с

  • автор:

Объявления вложенных классов

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

В следующем примере показано, как объявить вложенные классы.

// 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 ) 

В предыдущем интерфейсе несколько классов могут использовать службы этой функции, передав адрес памяти, в которую требуется скопировать сообщение об ошибке.

Использование классов внутри других классов

Бывает такое, что мы хотели бы использовать методы одного класса внутри другого, но не хотели бы наследовать от этого класса.

Почему мы не хотим наследовать?

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

Во-вторых, мы можем захотеть использовать несколько классов внутри другого класса, а с наследованием это не получится, ведь в 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; > > ?>

Давайте воспользуемся созданным классом Arr :

add(1); // добавляем в массив число 1 $arr->add(2); // добавляем в массив число 2 $arr->add(3); // добавляем в массив число 3 // Находим сумму квадратов и кубов: echo $arr->getSum23(); ?>

Самостоятельно повторите описанные мною классы Arr и SumHelper .

Создайте класс AvgHelper с методом getAvg , который параметром будет принимать массив и возвращать среднее арифметическое этого массива (сумма элементов делить на количество).

Добавьте в класс AvgHelper еще и метод getMeanSquare , который параметром будет принимать массив и возвращать среднее квадратичное этого массива (квадратный корень, извлеченный из суммы квадратов элементов, деленной на количество).

Добавьте в класс Arr метод getAvgMeanSum , который будет находить сумму среднего арифметического и среднего квадратичного из массива $this->nums .

Использование класса в другом классе

Author24 — интернет-сервис помощи студентам

Мне нужно, чтобы при создании объекта класса Object также создавался объект класса SimpleCollider, но в том объекте. Далее я хочу использовать методы объекта класса SimpleCollider через объект класса Object.
Извиняюсь за плохую формулировку, я весь день работал и устал, пишу поздно и ничего не понимаю. Может, по коду поймёте.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
class Object { public: //string File; float speed; int dir; Image image; Texture texture; Sprite sprite; ////////// class SimpleCollider { public: float getPos1X() { return Pos1X; } float getPos1Y() { return Pos1Y; } //////////////////////////// float getPos2X() { return Pos2X; } float getPos2Y() { return Pos2Y; } //////////////////////////// void setPos1X(float x) { Pos1X = x; } void setPos1Y(float y) { Pos1Y = y; } ////////////////////////// void setPos2X(float x) { Pos2X = x; } void setPos2Y(float y) { Pos2Y = y; } SimpleCollider(float Pos1X, float Pos1Y, float Pos2X, float Pos2Y) { this->Pos1X = Pos1X; this->Pos1Y = Pos1Y; this->Pos2X = Pos2X; this->Pos2Y = Pos2Y; } private: float Pos1X; float Pos1Y; float Pos2X; float Pos2Y; }; float Collider[1]; Object( float x, float y, string File, float scaleX,float scaleY, int W, int H) { speed = 0; this->x = x; this->y = y; this->speed = speed; image.loadFromFile("images/" + File); texture.loadFromImage(image); sprite.setTexture(texture); sprite.setScale(scaleX, scaleY); sprite.setOrigin(W/2, H/2); SimpleCollider Collider((x-W*scaleX),(y+H*scaleY),(x+W*scaleX),(y-H*scaleY)); } /////////// void update(float time) { switch(dir) { case 0: x -= speed * time; break; case 1: x += speed * time; break; case 2: y -= speed * time; break; case 3: y += speed * time; break; } speed = 0; sprite.setPosition(x,y); } Sprite draw() { return sprite; } float getX() { return x; } float getY() { return y; } void setX(float x) { this->x = x; } void setY(float y) { this->y = y; } private: float x,y; float health; bool isLife; float Size; };

Что должно быть дальше:

Object player(540, 635, "player.png",0.5, 0.5, 514, 514); coutplayer.Collider.getPos1X();

Как использовать метод из другого класса java

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

// Класс, где вызываем методы другого класса public class Example  public static void main(String[] args)  // Создаем объект класса Greetings greetings = new Greetings(); // Вызываем метод greetings.printHello(); // => Hello // Вызываем статический метод Greetings.printHexlet(); // => Hexlet > > class Greetings  public void printHello()  System.out.println("Hello"); > public static void printHexlet()  System.out.println("Hexlet"); > > 

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *