List<String> hrefs = (List<String>)((JavascriptExecutor)driver).executeScript(script);
Everything else is just for demonstrating that the code works. The line with executeScript is packed with a few things. The variable driver is of type WebDriver. The method executeScript is part of JavascriptExecutor. So you have to cast the driver variable to a JavascriptExecutor. Also, the signature for executeScript returns a class of type Object but we know it is really returning a List<String>. So we cast the result of executeScript to type List<String>. Your first question is telling you that you are doing a wrong thing. The executeScript is returning a List<String>. By telling the compiler it is returning a List<WebElement> is like buying a car and putting a label on it saying it is a Boeing 747 aircraft. When you cast you are telling the compiler what the method is ACTUALLY returning. Essentially by saying Krishnan's code is returning a List<WebElement> you are lying to the compiler.
The second question you have is saying I TELL the compiler I have a List<WebElement> but it is REALLY a List<String>. So it does not work. Bottom line, if you lie to the compiler it will believe you. Telling the compiler you have a List<WebElement> when it is really a List<String> does not make it a List<WebElement>. Another analogy would be, I walk into a store with a $5. I give it to the store owner and tell them it is a $100. Doesn't make it true. Now if I go into a store in India, put down a $5 USD and tell the store owner it is the same as 300 Rupee then that is true. In the case of Krishnan's code, the executeScript returns an Object. I cannot convert it to a List<WebElement> but I can convert it to List<String>.
To get the href and the link text you need to select a javascript data type which would return the data you need, create some Javascript which would return the appropriate structure then use executeScript to save it in an equivalent Java data type. This is really requires a much stronger knowledge of Java and Javascript. It might be easier to make two calls. One which returns the hrefs and one which returns the link text. Then you can assume item 1 in the hrefs list would match item 1 in the link text list.