9

I have the following interface and abstract class that implements it:

interface Walk {
    String walk();
}

public abstract class Animal implements Walk {
    abstract String MakeNoise();
}

And the following concrete implementations:

class Cat extends Animal {
    String MakeNoise() {
        return "Meow";
    }

    @Override
    String walk() {
        return "cat is walking";
    }
}

class Dog extends Animal {
    @Override
    String walk() {
        return "Dog is walking";
    }

    @Override
    String MakeNoise() {
        return "bark";
    }
}

class Human {
    public void Speak() {
        System.out.println("...Speaking...");
    }
}

Putting it all together:

class MainClass {
    public static void main(String[] args) {
        Random randomGen = new Random();

        Animal[] zoo = new Animal[4];
        zoo[0] = new Cat();
        zoo[1] = new Dog();
        zoo[2] = new Cat();
        zoo[3] = new Cat();
        // System.out.println(zoo[ randomGen.nextInt(2)].MakeNoise());
        for (Animal animal : zoo) {
            if (animal instanceof Dog) {
                Dog jeffrey = (Dog) animal;
                System.out.println(jeffrey.MakeNoise());
            }

        }
    }
}

I get this error

"walk() in Cat cannot implement walk() in Walk " .

Any ideas? thanks

8
  • 2
    That's not what the error says. Commented Dec 14, 2011 at 22:11
  • a question of my own.... should Animal provide an "implementation" (even if it is an abstract method) of walk()? Commented Dec 14, 2011 at 22:14
  • 2
    I still doubt that's what the error says. If you want effective help, give effective information: copy the error message verbatim into your question. Commented Dec 14, 2011 at 22:15
  • @SJuan: How does Animal redeclaring walk() as an abstract method make it provide an "implementation"? It would have absolutely no effect, other than on style. Or rather, if you were wondering if it needs to do so, the answer is no it doesn't, as long as Animal is declared abstract. Commented Dec 14, 2011 at 22:16
  • 1
    When typing in error messages, the only keys your fingers should be touching are ctl/command-c and ctl/command-v. Commented Dec 14, 2011 at 22:24

4 Answers 4

20

Methods in interfaces are implicitly public. However, methods in classes are package-visible by default. You cannot reduce the visibility of an overriden method, i.e. you can't do stuff like this:

class A {
    public foo() {}
}

class B extends A {
    private foo() {}  // No!
}

class C extends A {
    foo() {}          // No! foo is package-visible, which is lower than public
}

In your case, the solution is to declare walk() as public in Dog and Cat.

Sign up to request clarification or add additional context in comments.

2 Comments

What surprises me is that interface was declared as package not public. Thanks
That was a nice catch, Oli. I tell ya, the worst of the bugs I've had to deal with have always come down to silly stuff like this.
2

The error eclipse gives is:

Cannot reduce the visibility of the inherited method from Walk

The method must be public, because it is defined in an interface.

Comments

1

Interface methods must be public. You need to declare walk() as a public method in Cat.

Comments

1

Make String walk() implementations public. That will fix it

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.