views:

2470

answers:

6

Hello,

I have class B, which inherits from class A. The superclass A is abstract, containing one abstract method. I don't want to implement the abstract method in class B, therefore I need to declare class B as abstract as well. Declaring class B abstract, two things are working for me (the programs compile and run correctly):

1.) I don't declare any abstract methods in class B, even thought the class is abstract. This works, I assume, because the class inherits the abstract method of class A, and this is enough for the class to be declared as abstract: we don't need any other abstract methods directly declared in the class.

2.) I do declare the same abstract method in class B as it is declared in class A. This is some kind of overriding (?), not in the same sense as overriding in java (using the same header, but providing different implementation), here I just use again the same header of the method.

Both things are working, and I am not sure whether they are both Ok, and whether some of them is preferred (more correct) that the other. Are the two ways the same (do they mean the same to Java)?

Here I give some example classes, so that what I mean is more clear for you:

Case 1.):

public abstract class A {
    public abstract String giveSum();
}

public abstract class B extends A {

}

Case 2.):

public abstract class A {
    public abstract String giveSum();
}

public abstract class B extends A {
    public abstract String giveSum();
}

Regards

+8  A: 

They are functionally equal, but the first one is preferred because it's shorter and isn't weird.

Yoni Roit
How about "doesn't confuse the reader about whether a new method is being defined" rather than "isn't weird"? ;-)
joel.neely
"isn't weird" is shorter :-)
Yoni Roit
I like "isn't weird."
Zach Langley
+2  A: 

Go with #1. Rewriting the method declaration in the child class is confusing. And you actually don't need any abstract methods in an abstract class, regardless of whether the parent is abstract or not.

Zach Langley
But does it make sense to declare a class as abstract, if no abstract methods are declared in the class (and the class does not inherit from an abstract class?)
Ah, the post by Jared below answers this question.
+2  A: 

So, the question is: Which is preferred when sub classing an abstract class in java and don't want to provide implementation?

a) mark subclass as abstract too

b) mark subclass as abstract too AND re-write the method signature marked as abstract?

I would go for the first one:

a) Mark subclass as abstract too.

The former has already the abstract method declaration, there is no point in repeating it.

OscarRyz
+19  A: 

In Java, the abstract class annotation indicates that the class cannot be directly instantiated. A class could be declared abstract simply because it should never be instantiated (perhaps it contains only static methods), or because its subclasses should be instantiated instead.

It is not a requirement that abstract classes contain abstract methods (the inverse is true: a class containing one or more abstract methods must be abstract.)

The question of whether you should duplicate the abstract method definition might be perceived as a style question - but I would be hard pressed to come up with an argument in favor of duplicating the definition (the only argument I can come up with is in the case where the class hierarchy might change the semantics or use of the method, and thus you'd like to provide an additional javadoc in class B.)

The primary argument against re-definition of the abstract method is that duplicate code is bad - it makes refactoring more cumbersome and such (all the classic "don't duplicate code" arguments apply.)

Jared
+1: Excellent answer.
Software Monkey
A: 

Thank you very much, it is clear now.

+1  A: 

You are right, the two cases are equivalent. Case 1) is more simple, case 2) is code duplication - avoid it. But there may be one reason to do so:

If the method in class A does not return String but lets say C, class B may override it (since Java 5) with a more specific return type, lets say D (class extends C):

public abstract class A {
  public abstract C giveSum();
}

public abstract class B extends A {
  public abstract D giveSum();
}

public class C {
  ...
}

public class D extends C {
  ...
}
Arne Burmeister
http://en.wikipedia.org/wiki/Covariant_return_type . i think only implemented in java 1.5 ( http://java.sun.com/developer/JDCTechTips/2004/tt1201.html#2 )
Chii