На самом деле, все гораздо проще. Есть наша приватная группа, в которую хотелось бы автоматизировать инвайт пользователей нашего сайта. Вообще говоря изначально думали над 2-мя вариантами: автоинвайт или хотя бы автоматическое подтверждение запросов на вступление в группу.
Но как я понимаю, надежного способа нет?
С API для Standalone не работал, но как я понимаю там все равно какой-нибудь аналогичный токен выдается на относительно короткий срок, который постоянно надо подтверждать?
Ну кстати немного не соглашусь. Работу и учебу возможно совмещать, но просто не на ранних курсах, там это будет довольно тяжело.
Я, например, с конца 3-го курса одновременно работал и учился на дневном, что не помешало мне получить красный диплом.
Ну логика для сокрытия от наследования должна быть довольно простой:
1. private должны быть все переменные и методы, которые не служат для формирования абстракции нужного уровня. Т.е. например, есть внутренние переменные или методы, используемые для вычисления чего-то внутри других методов класса, но не имеющие к абстракции класса отношения. В моем первом примере это был массив данных, который выступал временным буфером, который служит для выполнения конкретной операции чтения.
2. private должны быть все те методы и переменные, логика работы с которым может быть известна и использоваться сторонними классами, и как следствие, изменение этих методов и переменных приведет к некорректной работе.
Кстати пример из окружающего мира.
Есть абстрактный класс «дерево», есть наследник «берёза». Вроде все логично, «береза» представляет из себя тоже «дерево», но расширяющая его. Если у «дерева» есть метод «расти», который предполагает деление клеток или чего там?) Логично же, что какое бы дерево ни было, все его наследники не должны следовать какой-то другой логике, отличной от деления клеток. И соответственно они не должны иметь доступ к этому методу и переопределять его.
Просто нужно видеть какая логика должна быть внутренней и явно не может быть изменена, а какая должна предоставляться наследникам. Т.е. по сути protected и private служат для той же инкапсуляции, только более низкого уровня
Только тут ничего даже близкого с адаптацией нет. Изменение работы фрейморка — дело разработчиков фреймварка. А вот адаптация его под себя и расширение его возможностей — Ваша задача. И она не подразумевает модификацию самого фреймворка вами :)
Продолжим немного пример. Допустим класс со скрытым счетчиком называется A. Допустим у него есть некоторый final (нельзя переопределить — из Jav) метод, возвращающий значение этой переменной.
Какой-то другой класс B в ядре фреймворка вполне может знать, как работает счетчик в A (что с точки зрения ООП не совсем корректно), и на основании этого знания выполнять другие свои функции.
Допустим переменная со счетчиком не скрыта и вы в наследнике A изменяете ее значение на какое-то некорректное.
Во время работы Ваша программа падает с каким-нибудь исключением, вы смотрите стек вызовов и видите, что исключение возникло в классе B. Но вы же его не трогали и как он работает — не знаете. И что в результате? Вы начинаете писать разработчикам фрейморвка, что у них баг.
… При этом использования private методов или свойств может сильно урезать расширение. Как поступать, когда использовать private, а когда protected?
Тут четко нужно видеть абстракцию класса и тогда таких вопросов возникать не будет. Совсем бестолковый пример, но все же: Вы создаете фреймворк, у Вас есть некий класс и статическое приватное поле, значение которого инкрементируется при создании нового экземпляра класса (или наследника) и декрементируется при удалении. С точки зрения абстракции класса это поле не имеет значения. Но для функционирования фреймворка это поле очень важно. Представьте если это значение не будет скрыто и другой разработчик, наследующий класс решит изменить его.
Вот и примерчик вспомнился. Только вчера писал потоковую оболочку для работы со специфическим буфером. Так вот в этом классе есть private массив байт, в который предварительно считываются данные из буфера, а потом этот массив конвертируется в необходимое значение. При этом из-за большого количество записей чтения, постоянно выделять память и освобождать непосредственно внутри метода не имеет смысла из-за накладных расходов.
Потом в связи с тем что возможна передача шифрованных данных, мне пришлось создать наследник этого класса, реализующий логику дешифрования. При этом сам процесс чтения данных то не изменился, добавилось только дополнительное преобразование данных после чтения.
Теперь вернемся к private массиву. Он используется только в родительском классе. С точки зрения его абстракции, дочерние классы не должны знать как он считывает данные, они только знают, что есть набор методов для чтения, которые они могут использовать или переопределять. К тому же более того, если бы дочерний класс знал об этом массиве и попытался бы его изменить, то все просто перестало бы функционировать корректно.
Вывод: private должны быть как минимум все переменные, которые не относятся к асбтракции класса. Но и опять же повторюсь, что еще лучше, чтобы все переменные были private, а для необходимых просто определять protected геттеры и сеттеры. А public и protected стоит объявлять только константы при необходимости.
Слишком долго я набирал сообщение, чтобы потом до конца понять суть проблемы…
Собственно конкретный пример сейчас не приведу. Но ведь вполне явно что может возникнуть необходимости из дочернего класса только читать значение некоторой переменной, но не присваивать ей значения. Тогда переменная как раз должна быть объявлена как private, а так же должен быть определен protected геттер для нее.
Спасибо за ответ. Но данный вариант не подходит. UML никак не предполагает построения иерархии вызовов методов. Он всего лишь позволяет определить связь между классами, но не на том уровне, на котором требуется. Т.е. если класс A вызывает метод класса B, который в свою очередь вызывает метод класса C, то UML-диаграммы по определению не должны отображать связь между A и C, и тем более показывать имена методов, через которые этот вызов осуществляется.
Я вот сейчас работают над несколькими проектами на Qt и на Java. У самого в этой паре душа лежит больше к Qt. Тут могу сказать, что для различных web-приложений куда больше подходит Java из-за довольно хорошего выбора компонент и простоты разработки. В остальном предпочитаю больше Qt.
Кстати, я вот уже год не занимаюсь разработкой на .Net, но каждый раз как перехожу к GUI, сразу же ностальгия по XAML. Такое бы да в Qt…
Я все к слову о кроссплатформенности. Если у Java все (или почти все) библиотеки кроссплатформенные. То вот у C++ далеко нет, хотя может я уже отстал от жизни?
И вообще, что Вы придираетесь к словам?:) Вы же, наверняка, прекрасно поняли, суть моих слов, что лучше смотреть в сторону кроссплатформенности, а не привязывать себя сразу только к Windows…
Наверное не точно выразился, речь идет не о C++, а о COM (и WinRT) :)
Ну и да, не забывайте, что на чистом C++ уже точно никто писать не будет, поэтому, если Вы еще раз взгляните на мое сообщение, я предложил как вариант использовать кроссплатформенные C++ фреймворки.
Гугление дало 2 возможных варианта:
1. Определить отдельно класс, реализующий интерфейс OnCompletionListener, и работать уже с ним.
2. Если юзается эмулятор, то проблема может быть в нем, и тогда стоит попробовать запустить на реальном устройстве.
Но как я понимаю, надежного способа нет?
С API для Standalone не работал, но как я понимаю там все равно какой-нибудь аналогичный токен выдается на относительно короткий срок, который постоянно надо подтверждать?