I was going through Screenshot code in selenium. Below is the code for it :
File src = ((TakesScreenshot)driver).getScreenshotAs(OutputType.File);
In the above line, TakesScreenshot is an interface and getScreenshotAs is a method. So what I understand from this is, we are typecasting driver into TakesScreenshot interface which essentially means that our driver will behave like TakesScreenshot from now after which getScreenshotAs method will be executed.
My question here is that an interface can only have abstract methods. So, how is getScreenshotAs method is executed through TakesScreenshot interface as it would not have any definition of this method. More precisely, where is getScreenshotAs method defined and how does the above line of code works ?
Adding a few more details :
TakesScreenshot --> an interface
driver --> instance of ChromeDriver class (WebDriver driver = new ChromeDriver())
getScreenshotAs --> method in TakesScreenshot interface.
The above code is used to take screenshot of webpages in selenium.
Well, as I understand, it's not actually a selenium-specific question, but basic Java question.
The meaning of the expression you provided:
is following: no matter what is the type of
drivervariable, in this line we are sure that it implementsTakesScreenshotinterface which hasgetScreenshotAsmethod. So we're casting type toTakesScreenshotand callgetScreenshotAsmethod on thedriverobject. The implementation of this method is inside realdriverclass whichever it is.To give you an example which will be really close to the question code (I made this method to accept
Objectso we really need to castoto the target interface. Don't do it in real code):where
Printableis some interface with methodprint:so if we have some implementation of
Printablelikewe can call
which result in line "Hello, username"
Edit:
As I can see in JavaDoc to selenium,
WebDriverinterface does not extendTakesScreenshotinterface. So if the type ofdrivervariable isWebDriverinterface you have to cast it.WebDriver driver = new ChromeDriver()- there is only reference of typeWebDriverfor compiler. Despite the fact that real class isChromeDrivercompiler doesn't know it. So in this case in order to callgetScreenshotAsmethod you have to castdrivertoTakesScreenshot(and it's safe asdriveris instance ofChromeDriverwhich implements bothWebDriverandTakesScreenshotinterfaces). Only after that you can callgetScreenshotAsmethod fromTakesScreenshotinterface.Well, as I understand, it's not actually a selenium-specific question, but basic Java question.
The meaning of the expression you provided:
is following: no matter what is the type of
drivervariable, in this line we are sure that it implementsTakesScreenshotinterface which hasgetScreenshotAsmethod. So we're casting type toTakesScreenshotand callgetScreenshotAsmethod on thedriverobject. The implementation of this method is inside realdriverclass whichever it is.To give you an example which will be really close to the question code (I made this method to accept
Objectso we really need to castoto the target interface. Don't do it in real code):where
Printableis some interface with methodprint:so if we have some implementation of
Printablelikewe can call
which result in line "Hello, username"
Edit:
As I can see in JavaDoc to selenium,
WebDriverinterface does not extendTakesScreenshotinterface. So if the type ofdrivervariable isWebDriverinterface you have to cast it.WebDriver driver = new ChromeDriver()- there is only reference of typeWebDriverfor compiler. Despite the fact that real class isChromeDrivercompiler doesn't know it. So in this case in order to callgetScreenshotAsmethod you have to castdrivertoTakesScreenshot(and it's safe asdriveris instance ofChromeDriverwhich implements bothWebDriverandTakesScreenshotinterfaces). Only after that you can callgetScreenshotAsmethod fromTakesScreenshotinterface.