0

I'm studying for Java SE 7 certification exam and I'm doing some boring excercises about inheritance and access modifiers.

But now I'm getting an unexpected behavior applying inheritance. In my base package com.testpkg I have an abstract class:

package com.testpkg;

public abstract class Abstract {

    public int test();

}

NOTE that I voluntarily omitted the abstract modifier for the test() method.

Then I have a concrete class extending Abstract in package com.testpkg.sub:

package com.testpkg.sub;

public class Concrete extends Abstract {

    public int test() {
        return 0;
    }
}

I test this classes using:

package com.testpkg;

import com.testpkg.sub.Concrete;

public class TestMain {

    public static void main(String[] args) {
        Abstract c = new Concrete();
        System.out.println(c.test());
    }
}

If I try to compile this, I obviously get two errors:

The method test() requires a body instead of a semicolon

But if I run test class: 0 is printed on console!

This seems very strange to me. Can you explain why the code is working even test() is wrongly declared in Abstract class?

NOTE I'm using Eclipse IDE to compile/run my code.

davioooh
  • 23,742
  • 39
  • 159
  • 250
  • How's your code running if it's not compiling? – Boj Nov 04 '13 at 11:28
  • 1
    @WIll I'm using Eclipse. It alerts that a compiling error exists, but allow me to run the code. – davioooh Nov 04 '13 at 11:34
  • I believe that's the answer to your question. Eclipse allows you to run "half baked" code. The reason why it runs fine here is because, at runtime, you never really depend on the specifics of the `Abstract` class so it doesn't really matter if you have this type of compile error in it. – aioobe Nov 04 '13 at 11:54
  • Have you tried cleaning your project prior to building? As others have pointed out you probably have a class file that is based on the version of the correct abstract class. – Benjamin Gale Nov 04 '13 at 12:04
  • @Benjamin Yes I already tried cleaning the project. Nothing changes. – davioooh Nov 04 '13 at 12:08
  • @aioobe Yes I suppose the problem could depend on this. Can you copy your comment as an answer so I can accept it? – davioooh Nov 04 '13 at 12:09

3 Answers3

2

You need an abstract qualifier on your test() method. You're likely running an old class file. If you change the value of your return statement to something besides 0, you will see that it isn't running this code.

arcy
  • 12,845
  • 12
  • 58
  • 103
  • 1
    Unfortunately is not true. I updated my code with different return values and the right value is always returned. Try it! – davioooh Nov 04 '13 at 11:37
  • Well, on my system, since there is a compilation error in the abstract class, the compiler does not create a class file (I did try it to verify). Since there is no class file for the abstract class, the program will not run. I guess you have a magic compiler that creates class files even though it tells you there is an error. Sounds like an exciting work environment, not being able to determine if compilation took place, and guessing what it produced if it did. Or there is still an old class file around for the abstract class, and changing the value in the concrete class keeps using it. – arcy Nov 04 '13 at 11:57
  • @davioooh: my eclipse doesn't do this. Just based on statistics, I'd say yous doesn't either. It isn't' unreasonable to blame your tools for things you don't understand, but if you truly want to understand what's happening, I suggest you dig further. – arcy Nov 04 '13 at 14:23
  • 1
    @rcook I'm not 'blaming' my tools. I completely agree with you when you say that if there is an error in a class, compiler should not produce any `.class` file. That is exacly what I expected, but I verified that Eclipse create an `Abstract.class` file under `bin` directory, so it's reasonable that my problem depends on this... – davioooh Nov 04 '13 at 14:39
1

Eclipse allows you to run "half baked" code. The reason why it runs fine here is because, at runtime, you never really depend on the specifics of the Abstract class so it doesn't really matter if you have this type of compile error in it.

aioobe
  • 413,195
  • 112
  • 811
  • 826
  • 1
    @aioobe: what do you mean by "half baked" code? Eclipse uses javac to compile code, and javac does not produce a class file with this error in it. If I create those three files in eclipse, there is no class file for the abstract class. If I try to run the main class, it says "Exception in thread "main" java.lang.Error: Unresolved compilation problems", and does not run. I believe the OP has a class file for the abstract class, I do not believe javac (or eclipse, however magic) produced it for him with this error in it. – arcy Nov 04 '13 at 14:39
  • 1
    no no. Eclipse has it's own compiler. Running programs with compile errors is one of its distinguishing features. See [this answer](http://stackoverflow.com/questions/3061654/what-is-the-difference-between-javac-and-the-eclipse-compiler) for instance. – aioobe Nov 04 '13 at 17:50
0

Yours class Abstract has compilation errors, because non abstract method should be defined, so it should have a body. abstract qualifier is optional only in case of interfaces.

Arek
  • 3,106
  • 3
  • 23
  • 32
  • 1
    As I wrote in my question, I voluntarily omitted the abstract modifier for the test() method. The problem is that the code is working correctly even if an error exists... – davioooh Nov 04 '13 at 11:49