2

So I was messing around with down-casting, trying to find what works and what doesn't. I have three classes: a base class Animal, and two derived classes Dog and Cat:

private class Animal {
}

private class Dog extends Animal {
}

private class Cat extends Animal {
}

The following code isn't allowed by the compiler for an obvious reason:

Dog dog = s.new Dog();
Cat cat = (Cat) dog;

This is because I'm casting one derived class to another derived class, which isn't possible. However, if I make Animal an interface type and Cat an interface type, then suddenly the compiler accepts it and doesn't say any problem, even though it isn't possible.

private interface Animal {

}

private class Dog implements Animal {

}

private interface Cat extends Animal {

}

As soon as I run the same code as before, it gives me an error, as expected.

user207421
  • 305,947
  • 44
  • 307
  • 483
nishantc1527
  • 376
  • 1
  • 12
  • I think the issue here is that the interface `Cat` is not an implementation, just a spec for an implementation which does not differ from interface `Animal` (yet). So, there is nothing wrong with casting a dog to a `Cat` interface. – Tim Biegeleisen Aug 16 '19 at 01:56
  • 1
    The compiler allows you to cast anything to anything; whether that works at runtimne is a different matter. A cast is you telling the compiler I know better and this thing you think is a `Foo` is also a `Bar`. – Elliott Frisch Aug 16 '19 at 01:56
  • I corrected your rather confused terminology. – user207421 Aug 16 '19 at 04:14

1 Answers1

5

The reason this is allowed is because it is perfectly possible for another class to exist, like this:

class CatDog extends Dog implements Cat {
}

Because such a class could exist, it is legal to cast an object of any (non-final) type to any interface type.

Jonathan Callen
  • 11,301
  • 2
  • 23
  • 44