0

In Stackoverflow I have got a link to the answer as below but its the definition and concept of abstract classes is provided not the logical reason

Abstract class in Java

In my understanding I think that abstract classes contain implemented methods reusable for the subclasses.

I checked the AbstractList and AbstractMap, all the methods of them are overridden in ArrayList and HashMap but the same implemented methods of AbstractList or AbstractMap are not used in ArrayList or HashMap.

Is there anything more to the abstract classes. Can anyone let me know

Community
  • 1
  • 1
niks
  • 1,013
  • 1
  • 9
  • 15
  • not all abstract classes contain (non-abstract) methods. in some cases, it's just a design choice. for instance 'I want to prevent the subclasses to extend any other class' kind of thing – Stultuske Jan 27 '16 at 13:11
  • In Java 8 there is less reason to use abstract classes as interface can now have code with `default` and `static` methods. What used to need an abstract class might only require interface(s) now. – Peter Lawrey Jan 27 '16 at 13:19

4 Answers4

1

In fact Abstract classes may or may not include abstract methods. Abstract classes cannot be instantiated, but they can be subclassed.

Why we use Abstract Classes ?

Suppose we were modeling the behavior of humans, by creating a class hierachy that started with a base class called Human. Human are capable of doing different things like speaking and walking and eating. Let's take the speaking behavior (example : greeting() method) every humain depending on his nationality have a different language : an English men would say : "Hello" and a Frensh men would say : "Bonjour" .

So we know that all Human can do greeting but with different language !

This is a good candidate for an abstract method (forcing subclasses to provide a custom implementation). Let's look at a very primitive Humain base class, which defines an abstract method for making a greeting and walk :

public abstract class Human
{

    //We know that humain walk the same way so we provide 
    //method implementation at this level
    public void walk()
    {
        System.out.println('I\'m walking !');
    }

    //We don't know at this level what's the language of the humain
    public abstract void greet ();

}

//This class inherit the walk() method and provide it's
//specific implementation for the greeting() method
public class EnglishMen extends Human {

    @Override
    public abstract void greet () {
        System.out.println('Hello :) ');
    }

}

//This class inherit the walk() method and provide it's
//specific implementation for the greeting() method
public class FrenshMen extends Human {

    @Override
    public abstract void greet () {
        System.out.println('Bonjour :) ');
    }

}

Now, any Humaun that wants to be instantiated (like an EnglishMen or FrenshMen) must implement the greeting method - otherwise it is impossible to create an instance of that class.

Note: When an abstract class is subclassed, the subclass usually provides implementations for all of the abstract methods in its parent class. However, if it does not, then the subclass must also be declared abstract.

Wael Sakhri
  • 367
  • 1
  • 8
0

An abstract class is a class that implements most of the functionality of an object but leaves critical functionality for you to implement.

When it is encouraged (or even expected) that implementations of an interface will be created it is common to provide all possible assistance to do that. This is where the Abstract... classes are extremely helpful. Not only do they implement the interface but they expose a minimal set of abstract methods that you must implement to achieve that.

Consider this implementation of a list that contains one single String using AbstractList:

class OneHelloList extends AbstractList<String> implements List<String> {

    @Override
    public int size() {
        return 1;
    }

    @Override
    public String get(int index) {
        return "Hello";
    }

}

public void test() {
    for (String s : new OneHelloList()) {
        System.out.println(s);
    }
}

See how simple it is for me to achieve the full functionality of a List with a very small code base.

Contrast that with what I would have to do to implement List without the AbstractList:

class TwoHellosList implements List<String> {

    @Override
    public int size() {
        return 2;
    }

    @Override
    public boolean isEmpty() {
        return false;
    }

    @Override
    public boolean contains(Object o) {
        return o.toString().equals("Hello");
    }

    @Override
    public Iterator<String> iterator() {
        return new Iterator<String>() {
            int count = 0;

            @Override
            public boolean hasNext() {
                return count < 2;
            }

            @Override
            public String next() {
                count += 1;
                return "Hello";
            }

        };
    }

    // The rest for you to complete.

    @Override
    public Object[] toArray() {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public <T> T[] toArray(T[] a) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public boolean add(String e) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public boolean remove(Object o) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public boolean containsAll(Collection<?> c) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public boolean addAll(Collection<? extends String> c) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public boolean addAll(int index, Collection<? extends String> c) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public boolean removeAll(Collection<?> c) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public boolean retainAll(Collection<?> c) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public void clear() {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public String get(int index) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public String set(int index, String element) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public void add(int index, String element) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public String remove(int index) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public int indexOf(Object o) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public int lastIndexOf(Object o) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public ListIterator<String> listIterator() {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public ListIterator<String> listIterator(int index) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public List<String> subList(int fromIndex, int toIndex) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

}
OldCurmudgeon
  • 60,862
  • 15
  • 108
  • 197
0

Abstract classes are similar to interfaces. You cannot instantiate them, and they may contain a mix of methods declared with or without an implementation. However, with abstract classes, you can declare fields that are not static and final, and define public, protected, and private concrete methods. With interfaces, all fields are automatically public, static, and final, and all methods that you declare or define (as default methods) are public. In addition, you can extend only one class, whether or not it is abstract, whereas you can implement any number of interfaces.

Which should you use, abstract classes or interfaces?

  • Consider using abstract classes if any of these statements apply to your situation:
    • You want to share code among several closely related classes.
    • You expect that classes that extend your abstract class have many common methods or fields, or require access modifiers other than public (such as protected and private).
    • You want to declare non-static or non-final fields. This enables you to define methods that can access and modify the state of the object to which they belong.
  • Consider using interfaces if any of these statements apply to your situation:
    • You expect that unrelated classes would implement your interface. For example, the interfaces Comparable and Cloneable are implemented by many unrelated classes.
    • You want to specify the behavior of a particular data type, but not concerned about who implements its behavior.
    • You want to take advantage of multiple inheritance of type.

realtime-examples

abstract-class-real-time-example

Community
  • 1
  • 1
Rahul Bhawar
  • 440
  • 6
  • 17
0

Abstract classes are also extremely useful in cases where the actual implementation is known but the domain model (data) is not known. For example, to insert into a database, you can write an abstract class

public abstract class DBUpdate{

protected insert(){

...//the actual implementation
}
 protected update(){

...//the actual implementation
 }
 protected delete(){

...//the actual implementation
}
//the fields of the subclasses can be obtained through reflection or some other method

Now, let's say that you have a table MyTable with columns a,b and c, which need to be inserted into the database

public class MyTable extends DBUpdate{

private String a;
private String b;
private String c;

 //add getters/setters here
}

Now, in order to insert a MyTable record, we should only create an instance of it and call the insert() method

....
MyTable myTable = new MyTable();
myTable.seta("a");
myTable.setb("b");
myTable.setc("c");

myTable.insert();

DBUpdate knows how to insert, update and delete data but it still needs to be subclassed (which basically tells DBUpdate which data needs to be updated)

dsp_user
  • 1,625
  • 2
  • 12
  • 21