2

This is probably a dumb question but I need to know. I have an interface as

import com.amazonaws.services.dynamodbv2.AmazonDynamoDBAsync;

public interface AsyncClient extends AmazonDynamoDBAsync{

}

And I have a ClientCreator class which has the method

import com.company.clients.AsyncClient;
public class ClientCreator {
        public static AsyncClient getAsyncClient() throws FileNotFoundException, IllegalArgumentException, IOException{
            AmazonDynamoDBAsync client = new AmazonDynamoDBAsyncClient(getCredentials());
            client.setRegion(getRegion());
            return (AsyncClient)client;
        }
        .
        .
        .

Here AmazonDynamoDBAsyncClient implements AmazonDynamoDBAsync and AsyncClient extends AmazonDynamoDBAsync, but this code would not work and throws

com.amazonaws.services.dynamodbv2.AmazonDynamoDBAsyncClient cannot be cast to com.company.clients.AsyncClient

but why?

ufucuk
  • 475
  • 9
  • 21
  • 1
    Does `AmazonDynamoDBAsyncClient` implement `AsyncClient`? – cHao Jan 06 '14 at 19:03
  • No it doesn't, and it can't. But it implements AmazonDynamoDBAsync and AsyncClient extends that one. – ufucuk Jan 06 '14 at 19:04
  • So, if `Poodle` implements `Animal` and `Cat` extends `Animal`, you're basically asking, "how do i treat a `Poodle` as a `Cat`?" – cHao Jan 06 '14 at 19:06
  • Here's some basic documentation on casting and inheritence in java http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html – Robert Beltran Jan 06 '14 at 19:07

1 Answers1

13

Basically you've got the hierarchy like this:

         AmazonDynamoDBAsync 
                  ^
                  |
     -----------------------------
     |                           |
AmazonDynamoDBAsyncClient   AsyncClient 

And you are trying to cast AmazonDynamoDBAsyncClient instance to AsyncClient, which isn't possible. Those are siblings. Take it like this: "Apple" and "Banana" are both "Fruit", but an "Apple" is not a "Banana".

Rohit Jain
  • 209,639
  • 45
  • 409
  • 525
  • Just logically somehow I feel like I must be able to cast, since Class1 and Interface2 actually shares methods. And casted object would get only the methods which is available in Interface1. But of course I might be completely wrong at all. – ufucuk Jan 06 '14 at 19:08
  • @ufucuk: You can't cast to something that isn't in the type's lineage, as Rohit points out. That's just fundamental. It doesn't matter how similar they are, they're different things by definition. Assuming `interface Base`, and we have `interface A extends Base` and `interface B extends Base` (neither of which adds anything to `Base`). you can't cast `A` to `B` (or vice-versa). `A` is not in `B`'s lineage, nor vice-versa. – T.J. Crowder Jan 06 '14 at 19:09
  • Ok that seems I have to read all up and down casting stuff again. Thanks. – ufucuk Jan 06 '14 at 19:11