ashes999
ashes999

Reputation: 10163

Returning a Subclass in Java when a Superclass is Expected

Edit: This didn't work because I had:

class Animal { ... }
class Horse extends Animal { ... }
class Unicorn extends **Animal** { ... }

Clearly, this is a typo, and Unicorn is supposed to extend Horse, not animal. And here, I thought I found a hole in Java's polymorphism!


Maybe it's just me, but this doesn't make sense. Let's assume I have two classes in Java, Horse and Unicorn (which is a subclass of Horse):

public class Horse {
  public String speak() {
    return "Wow, a talking horse!";
  }
}

public class Unicorn extends Horse {
  @Override
  public String speak() {
    return "Unicorns really exist?!";
  }
}

This code doesn't compile:

public Horse getHorse() {
  return new Unicorn(); // Doesn't compile
}

I get the compilation error "Cannot convert from Unicorn to Horse" under Eclipse using JRE or JSE 1.6.

Why doesn't it compile? Every unicorn is also a horse, and therefore, I'm returning a valid instance of horse ... aren't I?

My question is really about how polymorphism works in Java. I expect this to work. For what it's worth, this code compiles in .NET 2.0 (maybe that's why I expect it to work in Java, too).

Upvotes: 0

Views: 2394

Answers (3)

OscarRyz
OscarRyz

Reputation: 199333

Works as expected:

See it in action

Probably your error, is you have both classes defined in the same source file.

There should be only one public class per file ( or as in my case, many non public )

But, without the exact error message is only speculation.

Upvotes: 2

wds
wds

Reputation: 32303

This works:

public class Test {
    public static class Horse {
        public void speak() {
            System.out.println("I'm a horse");
        }
    }

    public static class Unicorn extends Horse {
        public void speak() {
            System.out.println("I'm a unicorn");
        }
    }

    public static void main(String[] args) {
        getHorse().speak();
    }

    public static Horse getHorse() {
        return new Unicorn();
    }
}

It's not fundamentally different from what you claim to be doing, so your problem must be elsewhere.

Upvotes: 1

Lukas Eder
Lukas Eder

Reputation: 221370

Did you write it exactly like this? because you can't have the parentheses in class definitions... e.g.

public class Horse() {

should be

public class Horse {

also

public class Unicorn extends Horse() {

should be

public class Unicorn extends Horse {

Upvotes: 7

Related Questions