7

Can have an abstract class implementing all of its methods-- with no abstract methods in it.

Eg.:

public abstract class someClass { 
    int a; 
    public someClass (int a) { this.a = a; } 
    public void m1 () { /* do something */ } 
    private void m2 () { /* do something else */ }  
}

What's the advantage, if any, of having such an abstract class compared to having the same class as a concrete one instead?

One i can think of is that, when i declare it as abstract, it won't be instantiated. however, i can have the same effect by making it concrete and its constructor(s) private.

TIA.

//==================

EDIT: One other use I can think of:

it may be extending another abstract class or implementing an interface without implementing that class's abstract methods-- although it is implementing all methods of its own. for whatever it' worth.

user3880721
  • 613
  • 6
  • 16
  • 2
    You may want to provide anybody from instantiating this class. – Kon Sep 05 '14 at 19:35
  • If you make the constructor private then you would be making it into a singleton or will need a public static method to get an instance of the class where as an abstract class helps you in inheritance ... – StackFlowed Sep 05 '14 at 19:36
  • Making all constructors `protected` (watch out for the default one) has a very similar effect and is in fact my preferred way of doing this. Maybe it's a typo in the OP. – 5gon12eder Sep 21 '14 at 12:02

9 Answers9

2
  • you can declare to implement an interface and don't provide implementation and then each child implicitly gets interface extended

  • you prevent to create instance of this class

  • you in future provide common implementation to all children
jmj
  • 237,923
  • 42
  • 401
  • 438
2

It has a conceptual meaning: this class has a behaviour which makes no sense on its own.

Granted, it's difficult to imagine such a scenario without well-defined extension points (i.e. abstract methods), but occasionally it will be a reasonably accurate model of your problem.

You can have something like this:

public abstract class ObjectWithId {
    private final String id;

    public ObjectWithId( String id ) {
       this.id = id;
    }

    public final String getId() {
       return id;
    }
}

And then you can extend it to declare different types of objects that have ids. Here you have a fully specified and implemented behaviour but no restriction on any other behaviours subclasses may exhibit.

Note though that a much neater way to model the same thing is to use composition instead of inheritance.

public final class ObjectWithId<T> {
    private final String id;
    private final T ob;

    public ObjectWithId( String id, T ob ) {
       this.id = id;
       this.ob = ob;
    }

    public String getId() {
       return id;
    }

    public T getObject() {
       return ob;
    }
}

But before generics were introduced (up to Java version 1.4), this wouldn't have been as elegant and obviously better than the abstract class solution because you'd have had to trade in type safety.

biziclop
  • 48,926
  • 12
  • 77
  • 104
2

As you pointed out, you can prevent the class from being instantiated by making it's constructor private. Othere than that, there is no benefit whatsoever. This is probably supported just to provide language completeness.

ventsyv
  • 3,316
  • 3
  • 27
  • 49
2

We generally use Abstraction concept with inheritance

Consider using abstract classes if any of these statements apply to your situation:

  • You want to share code among several closely related classes.

To answer your question,

Why declare a class with concrete methods Abstract?

One possible reason is to support inheritance without actually creating objects


Assume you have two classes one Abstract and other Concrete

Abstract class : AbsClass

abstract class AbsClass {
  int a = 5;

  //Constructor
  public AbsClass() {
    System.out.println(a);
  }

  void methodA() {
    System.out.println(a + 10);

  }

}

and Concrete class : ConcreteClass

class ConcreteClass {
  int a = 10;

 //Made the constructor Private to prevent from creating objects of this class
  private ConcreteClass() {
    System.out.println(a);

  }

  void methodA() {
    System.out.println(a + 10);
  }

}

The above two classes should function similarly (?) Until you try to Subclass them

class AbsImplementer extends AbsClass {
//Works fine

}

class ConcImplementer extends ConcreteClass {
//Compilation Error Implicit super constructor ConcreteClass() is not visible


}
Ravi Yenugu
  • 3,895
  • 5
  • 40
  • 58
1

It can be useful if you consider it an utility class.

ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
1

The practical difference is that you can't create an instance of it. You would have to subclass it and create an instance of the subclass.

As to WHY you would want to do this, in practice ... I'm hard pressed to think of a good reason. You could say that the class is only meaningful if someone creates a subclass that implements some function. But then why not make that function abstract in the super-class?

I wouldn't rule out the possibility that someone might come up with some example where this makes sense, but I can't think of one. Just because it's possible to write a piece of code and that code compiles successfully doesn't mean that that it makes sense. I mean, I can write "total_price = item_price * zip_code + customer_height_in_cubits - 7.879", but that doesn't mean such a line of code would be meaningful.

Jay
  • 26,876
  • 10
  • 61
  • 112
1

Well assume that you don't care whether the methods of the abstract class are implemented or abstract, but by design it has to be abstract so that when someone extends it, they have to add more methods or override the existing ones or use as is. If they don't want to override the methods then the default behavior is already provided in that abstract class.

In this abstract class, the only criteria you enforce is - one simply cannot instantiate that class and they have to have their only version of class before using it.

So in general, abstract class with few or all methods being implemented, is much better than having an interface which has no methods implemented at all. This is based on the assumption that you are using it as a single inheritance.

dganesh2002
  • 1,917
  • 1
  • 26
  • 29
1

Consider something similar to the NVI pattern (not sure what you'd call it in Java):

public abstract class A {
    public final void doSomething() {
        System.out.println("required");
        doOptional();
    }

    protected void doOptional() {
        System.out.println("optional");
    }
}

public class B extends A {
    @Override
    protected void doOptional() {
        System.out.println("overridden");
    }
}

For your public API, you only expose a public final method which cannot be overridden. It performs some required work inside there and an optional method. When extending this class, you can only override doOptional().

Calling B.doSomething() will always print "required" before it proceeds.

Since doOptional() is not abstract, there's no purely code reason that class A needs to be abstract. But it might be desired for your particular project. For example, a base service that is always extended into specific sub-projects.

spudone
  • 1,267
  • 7
  • 10
1

This can be useful for cases when the classes derived from the abstract base class must have some behaviour that is different from each other but that behaviour can not be abstracted as residing within a method that has the same signature for all the classes. Being unable to share a signature can occur if the different behaviour requires methods that are passed different primitive types. Because they use primitive types you can not use generics to express the similarity.

An abstract base class without any abstract methods is acting a bit like a marker interface, in that it is declaring that implementing classes must provide some behaviour without having that behaviour encapsulated within a new method with a signature that is the same for all implementations. You would use an abstract base class rather than a marker interface when the implementing classes have some behaviour in common, especially if the base class can implement it for the derived classes.

For example:

abstract class Sender {
   protected final void beginMessage() {
      ...
   }

   protected final void endMessage() {
      ...
   }

   protected final void appendToMessage(int x) {
      ...
   }
 }

 final class LongSender extends Sender {
    public void send(int a, int b, int c) {
       beginMessage();
       appendToMessage(a);
       appendToMessage(b);
       appendToMessage(c);
       endMessage();
    }
 }

 final class ShortSender extends Sender {
    public void send(int a) {
       beginMessage();
       appendToMessage(a);
       endMessage();
    }
 }
Raedwald
  • 46,613
  • 43
  • 151
  • 237