Explicit implicit в чем разница
В прошлой теме была рассмотрена тема перегрузки операторов. И с этой темой тесно связана тема перегрузки операторов преобразования типов.
Ранее мы рассматривали явные и неявные преобразования примитивных типов. Например:
int x = 50; byte y = (byte)x; // явное преобразование от int к byte int z = y; // неявное преобразование от byte к int
И было бы не плохо иметь возможность определять логику преобразования одних типов в другие. И с помощью перегрузки операторов мы можем это делать. Для этого в классе определяется метод следующей формы:
public static implicit|explicit operator Тип_в_который_надо_преобразовать(исходный_тип param) < // логика преобразования >
После модификаторов public static идет ключевое слово explicit (если преобразование явное, то есть нужна операция приведения типов) или implicit (если преобразование неявное). Затем идет ключевое слово operator и далее возвращаемый тип, в который надо преобразовать объект. В скобках в качестве параметра передается объект, который надо преобразовать.
Например, пусть у нас есть следующий класс Counter, который представляет счетчик-секундомер и который хранит количество секунд в свойстве Seconds:
class Counter < public int Seconds < get; set; >public static implicit operator Counter(int x) < return new Counter < Seconds = x >; > public static explicit operator int(Counter counter) < return counter.Seconds; >>
Первый оператор преобразует число — объект типа int к типу Counter. Его логика проста — создается новый объект Counter, у которого устанавливается свойство Seconds.
Второй оператор преобразует объект Counter к типу int, то есть получает из Counter число.
Примение операторов преобразования в программе:
Counter counter1 = new Counter < Seconds = 23 >; int x = (int)counter1; Console.WriteLine(x); // 23 Counter counter2 = x; Console.WriteLine(counter2.Seconds); // 23
Поскольку операция преобразования из Counter в int определена с ключевым словом explicit, то есть как явное преобразование, то в этом случае необходимо применить операцию приведения типов:
int x = (int)counter1;
В случае с операцией преобразования от int к Counter ничего подобного делать не надо, поскольку данная операция определена с ключевым словом implicit, то есть как неявная. Какие операции преобразования делать явными, а какие неявные, в данном случае не столь важно, это решает разработчик по своему усмотрению.
Следует учитывать, что оператор преобразования типов должен преобразовывать из типа или в тип, в котором этот оператор определен. То есть оператор преобразования, определенный в типе Counter, должен либо принимать в качестве параметра объект типа Counter, либо возвращать объект типа Counter.
Рассмотрим также более сложные преобразования, к примеру, из одного составного типа в другой составной тип. Допустим, у нас есть еще класс Timer:
class Timer < public int Hours < get; set; >public int Minutes < get; set; >public int Seconds < get; set; >> class Counter < public int Seconds < get; set; >public static implicit operator Counter(int x) < return new Counter < Seconds = x >; > public static explicit operator int(Counter counter) < return counter.Seconds; >public static explicit operator Counter(Timer timer) < int h = timer.Hours * 3600; int m = timer.Minutes * 60; return new Counter < Seconds = h + m + timer.Seconds >; > public static implicit operator Timer(Counter counter) < int h = counter.Seconds / 3600; int m = (counter.Seconds % 3600) / 60; int s = counter.Seconds % 60; return new Timer < Hours = h, Minutes = m, Seconds = s >; > >
Класс Timer представляет условный таймер, который хранит часы, минуты и секунды. Класс Counter представляет условный счетчик-секундомер, который хранит количество секунд. Исходя из этого мы можем определить некоторую логику преобразования из одного типа к другому, то есть получение из секунд в объекте Counter часов, минут и секунд в объекте Timer. Например, 3675 секунд по сути это 1 час, 1 минута и 15 секунд
Применение операций преобразования:
Counter counter1 = new Counter < Seconds = 115 >; Timer timer = counter1; Console.WriteLine($"::"); // 0:1:55 Counter counter2 = (Counter)timer; Console.WriteLine(counter2.Seconds); //115
- Вопросы для самопроверки
- Упражнения
Чем отличаются явный (explicit) и неявный (implicit) интенты?
Интенты используются для старта базовых компонентов. Система понимает какой компонент стартовать по атрибутам объекта Intent.
Explicit intent явно содержит информацию о классе компонента. Это может быть объект Class , переданный в конструкторе Intent(context: Context, cls: Class) или методом setClass(context: Context, cls: Class), или объект класса ComponentName , переданный методом setComponent(componentName: ComponentName).
Явные интенты часто используются для старта компонентов внутри приложения, т.к. имена классов известны.
Например startActivity(Intent(context, MyHomeActivity::class.java)) – это старт активити с явным интентом.
Implicit intent не содержит информацию о конкретном компоненте. Система использует косвенные атрибуты, такие как action , type и category для выбора стартуемого компонента. Механизм поиска компонента по атрибутам неявного интента называется Intent Resolution и будет разобран в следующем посте.
Неявные интенты часто используются для старта компонентов других приложений.
Например startActivity(Intent(Intent.ACTION_CALL, Uri.parse(«tel:$number»))) – неявный интент, стартующий активити, которая выполнит звонок по заданному номеру.
Implicit и Explicit: в чем разница?

В английском языке есть много слов, которые, несмотря на то, что очень похожи по звучанию, имеют совершенно разные значения. Слова Implicit и Explicit — это именно тот случай, когда замена одного слова другим может привести к путанице и проблемам понимания.
Эти два слова имеют почти противоположные значения, но их часто путают из-за сходного звучания. Обязательно запомните, что смысл у этих терминов прямо противоположный, так что вы должны быть уверены, что используете правильное значение.
В этой статье я хочу напомнить вам точные определения слов Implicit и Explicit, объяснить их различия и попросить вас еще раз убедиться, что вы правильно понимаете их смысл.
Прочитав эту статью до конца, вы больше никогда не будете задавать себе вопрос: “Какое слово я прямо сейчас должен выбрать — Implicit или Explicit?”
Когда использовать Implicit
Толковые словари английского языка определяют слово Implicit следующим образом: “то, что подразумевается или понимается, но не высказано прямо”. Таким образом, что-то является неявным (Implicit), когда оно не указано прямо, но либо подразумевается в формулировке, либо необходимо для достижения цели. Например,
- В его произведениях неявно присутствует мораль. = There is a morality implicit in his writings.
- Она намекнула, что ей нравятся белые туфли, сказав, что ей нравятся все цвета, кроме бежевого. = She implicitly said she likes white shoes by saying she likes all colours but tan.
В первом примере автор, о котором говорится, может не приводить в своих текстах ясного или прямого изложения моральных принципов, но читатель воспринимает их через персонажей, их действия и их переживания.
Во втором примере женщина заявляет, что ей нравится обувь всех цветов, кроме бежевого. Хотя она прямо не говорит, что ей нравятся белые туфли, она делает это косвенно, потому что белый цвет — это не бежевый.
Когда использовать Explicit
Английский толковый словарь дает такое определение слову Explicit: “что-то, выраженое полностью и ясно, и не оставляет ничего подразумеваемого.” Что-то является явным (Explicit), когда оно четко сформулировано и изложено, не оставляя места для путаницы, как при написании контракта или устава. Например,
- В законе четко указывалось, чьи налоговые ставки должны быть повышены. = The law was explicit in whose tax rates were to be raised.
- Он прямо сказал, что вы не пойдете на этот концерт. = He said explicitly, you will not attend that concert.
В обоих этих примерах слово Explicit используется для указания на то, что что-то было ясно и недвусмысленно выражено или указано. Здесь нет места сомнениям, потому что все сообщается четко и прямо.
В чем главное отличие между Implicit и Explicit
Теперь вы понимаете, что именно отличает эти два слова?
- Что-то подразумевается, когда оно не указывается прямо. — Implicit
- Что-то является явным, когда оно прямо заявлено и не оставляет места для неопределенности.- Explicit
Вот еще несколько предложений
- The speaker’s intentions were not made Explicit. = Намерения говорящего не были явными.
- The students found an Implicit political statement in their teacher’s remarks. = Учащиеся нашли скрытое политическое заявление в замечаниях своего учителя.
- Let me be Explicit, I do not support this. = Позвольте мне говорить открыто, я не поддерживаю это.
- We have not finalized the decision, but have an Implicit agreement. = Мы еще не приняли окончательное решение, но имеем неявное соглашение.
Как запомнить разницу
Предлагаю вам очень удобный трюк, который поможет запомнить разницу между этими словами. Научитесь им пользоваться, и вы никогда не ошибетесь, когда перед вами встанет вопрос — какое слово выбрать Implicit или Explicit?
Хороший способ отделить явное от неявного — помнить, что неявное (Implicit) — это нечто подразумеваемое (Implied) или косвенное (Indirect). Как видите, все три слова начинаются с буквы «I”.
Резюме
Английские прилагательные Implicit и Explicit имеют почти противоположные значения, поэтому крайне важно помнить об их разнице и никогда не путать эти слова в тексте.
- Implicit (неявное) — это то, что подразумевается или утверждается косвенно.
- Explicit (явное) — это то, что прямо указано и прописано.
Читайте мои статьи и не путайте английские слова
- В чем разница между Cite и Quote
- Почему англичане различают Home и House
- Choose и Chose: в чем разница?
- Bar и Pub — это одно и то же?
- Изучаем английские слова Device и Devise
Способы ожидания в Java и Selenium
Обзор опций для написания ожиданий в автотестах, которые помогут организовать их работу в удобной форме.
Рассказывает Валерия, QA Automation Engineer в Noveo
Ожидания — не самый приятный процесс, где бы он ни происходил. Ожидания в автотестах — отдельная боль. Избавиться от них невозможно, но есть способы организовать их работу в более удобной форме, нежели Thread.sleep() .
Чтобы собрать вместе и систематизировать информацию по этой теме, рассмотрю все варианты написания ожиданий для автоматизированного тестирования UI посредством Java и Selenium, с которыми мне приходилось работать, а именно ожидания, предоставляемые Selenium, возможность написания собственных ожиданий и библиотека Awaitility.
Selenium waiting methods
Implicit Wait
Implicit Wait, или неявное ожидание, — пожалуй, самый популярный способ ожидания в Selenium благодаря своей легкости в использовании.
Чтобы использовать Implicit Wait в автотестестах, достаточно:
- установить его всего 1 раз,
- указать вручную лимит ожидания.
После того, как команда исполнится, Implicit Wait будет действовать на протяжении всего пробега автотестов и ожидать указанное время прежде, чем выбросить NoSuchElementException (или не выбрасывать, если необходимый элемент на странице найден). Не устанавливать Implicit Wait равносильно нулевому лимиту времени, и исключение пробросится сразу.
Чтобы установить Implicit Wait, необходимо написать всего одну строку после установки драйвера, и таким образом мы установим лимит ожидания 10 секунд:
Implicit Wait можно использовать для:
- ожидания полной загрузки страницы — pageLoadTimeout() ;
- ожидания появления элемента на странице — implicitlyWait() ;
- ожидания выполнения асинхронного запроса — setScriptTimeout() ;
Установка использования неявного ожидания будет выглядеть следующим образом:
@BeforeMethod (alwaysRun = true) public void setUpDriver() < //Set up driver ChromeOptions options = new ChromeOptions(); WebDriverManager.chromedriver().setup(); driver = new ChromeDriver(options); //Set implicit wait: //wait for WebElement driver.manage().timeouts().implicitlyWait(5000, TimeUnit.MILLISECONDS); //wait for loading page driver.manage().timeouts().pageLoadTimeout(10000, TimeUnit.MILLISECONDS); //wait for an asynchronous script to finish execution driver.manage().timeouts().setScriptTimeout(5000, TimeUnit.MILLISECONDS); >@Test (description = "Open url") public void openUrl() < //Open browser driver.manage().window().setSize(new Dimension(1280, 970)); //Get url driver.get("https://some_site.com"); //Search an element WebElement element = driver.findElement(By.id("some-id")); Assert.assertTrue(element.isDisplayed()); >@AfterMethod (alwaysRun = true) public void closeBrowser() < //Close browser driver.quit(); >
Explicit Wait
Explicit wait, или явное ожидание, чаще используется для ожидания определенного условия, которое должно быть выполнено прежде, чем тест пойдет дальше.
О явном ожидании стоит помнить следующие вещи:
- ожидание сработает именно там, где оно указано;
- как и неявному ожиданию, ему необходимо указать лимит времени;
- ожидает выполнения необходимого условия;
- ждет завершения Ajax request.
Использовать явное ожидание можно через WebDriverWait . Инициализация будет происходить следующим образом:
WebDriverWait wait = new WebDriverWait(driver,10);
где driver является референсом к нашему используемому WebDriver , а число 10 — TimeOut в секундах.
В тесте само ожидание уже будет выглядеть примерно так:
wait.until(ExpectedConditions.invisibilityOfElementLocated (By.cssSelector("element"));
Класс ExpectedConditions предоставляет нам ряд вещей, которых мы можем дожидаться во время пробега теста. Они все достаточно легко читаемы, что облегчит жизнь как вам, так и людям, которым, возможно, придется поддерживать ваши автотесты.
Вот полный список всего, что вам предлагает подождать ExpectedConditions :
- alertIsPresent()
- elementSelectionStateToBe()
- elementToBeClickable()
- elementToBeSelected()
- frameToBeAvaliableAndSwitchToIt()
- invisibilityOfTheElementLocated()
- invisibilityOfElementWithText()
- presenceOfAllElementsLocatedBy()
- presenceOfElementLocated()
- textToBePresentInElement()
- textToBePresentInElementLocated()
- textToBePresentInElementValue()
- titleIs()
- titleContains()
- visibilityOf()
- visibilityOfAllElements()
- visibilityOfAllElementsLocatedBy()
- visibilityOfElementLocated()
В тесте создание и использование неявного ожидания будут выглядеть следующим образом:
private WebDriver driver; private WebDriverWait wait; private WebElement exampleElement; @BeforeMethod(alwaysRun = true) public void setUpDriver() < //Set up driver ChromeOptions options = new ChromeOptions(); WebDriverManager.chromedriver().setup(); driver = new ChromeDriver(options); //Set explicit wait wait = new WebDriverWait(driver, 10); >@Test(description = "Open url") public void openUrl() < //Open browser driver.manage().window().setSize(new Dimension(1280, 970)); //Get url driver.get("https://some-site.com"); //Wait until blockUI disappear wait.until(ExpectedConditions.invisibilityOfElementLocated (By.cssSelector("element"))); wait.until(ExpectedConditions.invisibilityOf(exampleElement)); //Search an element WebElement element = driver.findElement(By.id("some-id")); Assert.assertTrue(element.isDisplayed()); //Click element element.click(); //Wait until alert is present wait.until(ExpectedConditions.alertIsPresent()); driver.switchTo().alert().accept(); >@AfterMethod(alwaysRun = true) public void closeBrowser() < //Close browser driver.quit(); >
Разница между Implicit и Explicit Wait
Написание собственных ожиданий
Ожидания Selenium не всегда способны удовлетворить потребности тестировщика. В таких случаях мы можем сами написать методы, которые удержат автотесты от падения. Работать кастомные ожидания будут по тому же принципу, что и Explicit Wait, т.е. срабатывать в той части теста, в которой указаны, а условие, которого необходимо дождаться, нужно написать самим как некий аналог класса ExpectedConditions . Хранить ли свои условия в отдельном классе или в том же, где и написанный способ ожидания, и нужно ли разделять метод ожидания и условие или достаточно будет оставить их прописанными в едином методе, зависит от условий проекта и предпочтений тестировщика.
Чтобы написать ожидание самим, потребуется не так много: старый добрый цикл while и System.currentTimeMillis() .
Выглядеть это может примерно таким образом:
public static void waitForInvisibilityOfElement(WebElement element) < float waitingTime = 0; //Start loading time of waiting for invisibility of element startLoadingTime = System.currentTimeMillis(); while (element.isDisplayed())< //If element is still presented, verify if the //maximum of waiting time is reached if(waitingTime else < System.out.println("Condition wasn't executed with time limit"); break; >> //If the element disappeared, log the loading time of the if(!element.isDisplayed()) < System.out.println("Condition was executed in " + waitingTime + " seconds"); >>
Условие, которое мы ждем в этом примере — element.isDisplayed() , его можно вынести в отдельный метод, возвращающий boolean , и таким образом сам метод ожидания можно прописать единожды и просто передавать туда разные условия в формате boolean .
Awaitility library
Пожалуй, лучшее, ну или, по крайней мере, мое любимое, решение проблемы ожиданий. Awaitility применима не только в автоматизации тестирования, однако я ограничусь рассмотрением ее использования на примерах тестов. Эта библиотека упростит вам жизнь при написании собственных ожиданий; все, что сказано про аналог кастомных ожиданий с Explicit Wait и ExpectedConditions , будет справедливо и здесь. То же касается и того, как вы предпочтете прописать условия, которых хотите дождаться. В рамках этой статьи рассмотрена только часть возможностей данной библиотеки. Если вам интересно почитать обо всех возможностях, можете ознакомиться с официальной документацией. Здесь я хочу обратить внимание на те моменты, которые мне показались максимально полезными, и просто поделиться тем, что есть такая замечательная штука, которая помогает стабилизировать автотесты.
Awaitility library позволит:
- дождаться выполнения асинхронных запросов;
- установить как максимум, так и минимум ожидаемого времени;
- проигнорировать выпадающие исключения (в таком случае по истечению лимита времени будет выброшен ConditionTimeoutException );
- использовать Assertion в качестве ожидаемого условия;
- использовать polling.
Синтаксис довольно читабельный; Awaitility позволяет понять, что и куда вызывается для определения лимита времени, игнорирования исключений, где устанавливаем polling и чего ожидаем в финале нашего метода. Внутреннее написание ожидания может выглядеть так — остается только вызвать его в тесте. Хранить подобные методы стоит все же отдельно от тестов.
public static void waitVisibleElement(WebElement we)
Отдельным примером хочу показать ожидание Assertion, именно этот метод кажется мне особенно удобным, так как убивает сразу двух зайцев и позволяет не прописывать лишних строк кода:
/** * Wait until two lists became equal * @param actualValues - actual values * @param requiredValues - expected values */ public static void waitOfAssertionForLists(List actualValues, List requiredValues) < given().ignoreExceptions().await().atMost(10, TimeUnit.SECONDS) .untilAsserted(() ->Assert.assertEquals (getValuesFromDropDown(actualValues), requiredValues)); > //Get text values from list of WebElements private static List getValuesFromDropDown(List wes)< List actualValuesInDropDown = new ArrayList<>(); for (WebElement we : wes) < if(we.isDisplayed() && we.getText().trim().length() >0) < actualValuesInDropDown.add(we.getText().trim()); >> return actualValuesInDropDown; >
Это та информация, которой я хотела поделиться об ожиданиях.
Более подробно вы можете ознакомиться с Awaitility по ссылке.