views:

759

answers:

9

What is an "abstract class" in Java?

+3  A: 

It's a class that cannot be instantiated, and forces implementing classes to, possibly, implement abstract methods that it outlines.

Noon Silk
+3  A: 

Take a look at this:

http://java.sun.com/docs/books/tutorial/java/IandI/abstract.html

ZiG
+16  A: 

A Java class becomes abstract under the following conditions:

1. At least one of the methods is marked as abstract:

public abstract void myMethod()

In that case the compiler forces you to mark the whole class as abstract.

2. The class is marked as abstract:

abstract class MyClass

As already said: If you have an abstract method the compiler forces you to mark the whole class as abstract. But even if you don't have any abstract method you can still mark the class as abstract.

Common use:

A common use of abstract classes is to provide an outline of a class similar like an interface does. But unlike an interface it can already provide functionality, i.e. some parts of the class are implemented and some parts are just outlined with a method declaration. ("abstract")

An abstract class cannot be instantiated, but you can create a concrete class based on an abstract class, which then can be instantiated. To do so you have to inherit from the abstract class and override the abstract methods, i.e. implement them.

DR
Nitpick: the second 'condition' is redundant, since you can only declare an abstract method in a class that is explicitly declared as abstract.
Stephen C
Agreed, the advice is not really correct, or well written, it's just formatted nicely.
Noon Silk
Agreed, too :) I updated my answer.
DR
But your advice 'to make a class concrete' is worded wrong as well. You don't *make* a class concrete, it either is, or isn't, depending on if it's abstract or not.
Noon Silk
*doh*, not enough caffeine yet. Updated again, thank's for the hint.
DR
This is just plain wrong. An abstract class doesn't have to have any abstract methods. You can make an abstract class without methods, or with only concrete methods.
Jorn
I'm not sure I understand what you are saying. I never wrote something like that, not even in the less-then-perfect first versions. On the contrary: I explicitly state what you are saying: "But even if you don't have any abstract method you can still mark a class as abstract."
DR
+1  A: 

Simply speaking, you can think of an abstract class as like an Interface with a bit more capabilities.

You cannot instantiate an Interface, which also holds for an abstract class.

On your interface you can just define the method headers and ALL of the implementers are forced to implement all of them. On an abstract class you can also define your method headers but here - to the difference of the interface - you can also define the body (usually a default implementation) of the method. Moreover when other classes extend (note, not implement and therefore you can also have just one abstract class per child class) your abstract class, they are not forced to implement all of your methods of your abstract class, unless you specified an abstract method (in such case it works like for interfaces, you cannot define the method body).

public abstract class MyAbstractClass{
  public abstract void DoSomething();
}

Otherwise for normal methods of an abstract class, the "inheriters" can either just use the default behavior or override it, as usual.

Example:

public abstract class MyAbstractClass{

  public int CalculateCost(int amount){
     //do some default calculations
     //this can be overriden by subclasses if needed
  }

  //this MUST be implemented by subclasses
  public abstract void DoSomething();
}
Juri
This answer isn't helpful if the OP doesn't know what an interface is. Since abstract classes and interfaces are interrelated, it's highly unlikely that the OP would know one without knowing the other.
Imagist
But it could be. It could be that he just knows what an interface is and how it works, and then he comes across abstract classes and wonders why one should need them. Couldn't that be?
Juri
+1  A: 

Solution - base class (abstract)

public abstract class Place {

String Name; String Postcode; String County; String Area;

Place () {

    }

public static Place make(String Incoming) { if (Incoming.length() < 61) return (null);

    String Name = (Incoming.substring(4,26)).trim();
    String County = (Incoming.substring(27,48)).trim();
    String Postcode = (Incoming.substring(48,61)).trim();
    String Area = (Incoming.substring(61)).trim();

    Place created;
    if (Name.equalsIgnoreCase(Area)) {
            created = new Area(Area,County,Postcode);
    } else {
            created = new District(Name,County,Postcode,Area);
    }
    return (created);
    }

public String getName() { return (Name); }

public String getPostcode() { return (Postcode); }

public String getCounty() { return (County); }

public abstract String getArea();

}

Ashvin Ranpariya
try formatting all code as code, and please add some explanation, right now this can hardly be considered an answer.
NomeN
A: 

Little addition to all these posts.

Sometimes you may want to declare a class and yet not know how to define all of the methods that belong to that class. For example, you may want to declare a class called Writer and include in it a member method called write(). However, you don't know how to code write() because it is different for each type of Writer devices. Of course, you plan to handle this by deriving subclass of Writer, such as Printer, Disk, Network and Console.

adatapost
A: 

An abstract class can not be directly instantiated, but must be derived from to be usable. A class MUST be abstract if it contains abstract methods: either directly

abstract class Foo {
    abstract void someMethod();
}

or indirectly

interface IFoo {
    void someMethod();
}

abstract class Foo2 implements IFoo {
}

However, a class can be abstract without containing abstract methods. Its a way to prevent direct instantation, e.g.

abstract class Foo3 {
}

class Bar extends Foo3 {

}

Foo3 myVar = new Foo3(); // illegal! class is abstract
Foo3 myVar = new Bar(); // allowed!

The latter style of abstract classes may be used to create "interface-like" classes. Unlike interfaces an abstract class is allowed to contain non-abstract methods and instance variables. You can use this to provide some base functionality to extending classes.

Another frequent pattern is to implement the main functionality in the abstract class and define part of the algorithm in an abstract method to be implemented by an extending class. Stupid example:

abstract class Processor {
    protected abstract int[] filterInput(int[] unfiltered);

    public int process(int[] values) {
        int[] filtered = filterInput(values);
        // do something with filtered input
    }
}

class EvenValues extends Processor {
    protected int[] filterInput(int[] unfiltered) {
        // remove odd numbers
    }
}

class OddValues extends Processor {
    protected int[] filterInput(int[] unfiltered) {
        // remove even numbers
    }
}
janko
+6  A: 

An abstract class is a class which cannot be instantiated. An abstract class is used by creating an inheriting subclass that can be instantiated. An abstract class does a few things for the inheriting subclass:

  1. Define methods which can be used by the inheriting subclass.
  2. Define abstract methods which the inheriting subclass must implement.
  3. Provide a common interface which allows the subclass to be interchanged with all other subclasses.

Here's an example:

abstract public class AbstractClass
{
    abstract public void abstractMethod();
    public void implementedMethod() { System.out.print("implementedMethod()"); }
    final public void finalMethod() { System.out.print("finalMethod()"); }
}

Notice that "abstractMethod()" doesn't have any method body. Because of this, you can't do the following:

public class ImplementingClass extends AbstractClass
{
    // ERROR!
}

There's no method that implements abstractMethod()! So there's no way for the JVM to know what it's supposed to do when it gets something like new ImplementingClass().abstractMethod().

Here's a correct ImplementingClass.

public class ImplementingClass extends AbstractClass
{
    public void abstractMethod() { System.out.print("abstractMethod()"); }
}

Notice that you don't have to define implementedMethod() or finalMethod(). They were already defined by AbstractClass.

Here's another correct ImplementingClass.

public class ImplementingClass extends AbstractClass
{
    public void abstractMethod() { System.out.print("abstractMethod()"); }
    public void implementedMethod() { System.out.print("Overridden!"); }
}

In this case, you have overridden implementedMethod().

However, because of the final keyword, the following is not possible.

public class ImplementingClass extends AbstractClass
{
    public void abstractMethod() { System.out.print("abstractMethod()"); }
    public void implementedMethod() { System.out.print("Overridden!"); }
    public void finalMethod() { System.out.print("ERROR!"); }
}

You can't do this because the implementation of finalMethod() in AbstractClass is marked as the final implementation of finalMethod(): no other implementations will be allowed, ever.

Now you can also implement an abstract class twice:

public class ImplementingClass extends AbstractClass
{
    public void abstractMethod() { System.out.print("abstractMethod()"); }
    public void implementedMethod() { System.out.print("Overridden!"); }
}

// In a separate file.
public class SecondImplementingClass extends AbstractClass
{
    public void abstractMethod() { System.out.print("second abstractMethod()"); }
}

Now somewhere you could write another method.

public tryItOut()
{
    ImplementingClass a = new ImplementingClass();
    SecondImplementingClass b = new SecondImplementingClass();
    AbstractClass c = new ImplementingClass();
    AbstractClass d = new ImplementingClass();

    a.abstractMethod();    // prints "abstractMethod()"
    a.implementedMethod(); // prints "Overridden!"
    a.finalMethod();       // prints "finalMethod()"
    b.abstractMethod();    // prints "second abstractMethod()"
    b.implementedMethod(); // prints "implementedMethod()"
    b.finalMethod();       // prints "finalMethod()"
    c.abstractMethod();    // prints "abstractMethod()"
    c.implementedMethod(); // prints "implementedMethod()"
    c.finalMethod();       // prints "finalMethod()"
    d.abstractMethod();    // prints "second abstractMethod()"
    d.implementedMethod(); // prints "implementedMethod()"
    d.finalMethod();       // prints "finalMethod()"
}

Notice that even though ImplementingClass overrode implementedMethod(), when ImplementingClass was being treated as an instance of AbstractClass, the method from AbstractClass was called. To call the method from ImplementingClass from the c instance, you would have to case it like ((ImplementingClass) c).implementedMethod();.

Lastly, you cannot do the following:

public class ImplementingClass extends AbstractClass, SomeOtherAbstractClass
{
    ... // implementation
}

Only one class can be extended at a time. If you need to extend multiple classes, they have to be interfaces. You can do this:

public class ImplementingClass extends AbstractClass implements InterfaceA, InterfaceB
{
    ... // implementation
}

Here's an example interface:

interface InterfaceA
{
    void interfaceMethod();
}

This is basically the same as:

abstract public class InterfaceA
{
    abstract public void interfaceMethod();
}

The only difference is that the second way doesn't let the compiler know that it's actually an interface. This can be useful if you want people to only implement your interface and no others. However, as a general beginner rule of thumb, if your abstract class only has abstract methods, you should probably make it an interface.

The following is illegal:

interface InterfaceB
{
    void interfaceMethod() { System.out.print("ERROR!"); }
}

You cannot implement methods in an interface. This means that if you implement two different interfaces, the different methods in those interfaces can't collide. Since all the methods in an interface are abstract, you have to implement the method, and since your method is the only implementation in the inheritance tree, the compiler knows that it has to use your method.

Imagist
+1  A: 

Get your answers here:

http://stackoverflow.com/questions/1298191/java-abstract-class-without-abstract-methods

http://stackoverflow.com/questions/1298369/java-abstract-class

http://stackoverflow.com/questions/1299398/abstract-class-java-basics

BTW - those are question you asked recently. Think about a new question to build up reputation...

Edit:

Just realized, that the posters of this and the referenced questions have the same or at least similiar name but the user-id is always different. So either, there's a technical problem, that keyur has problems logging in again and finding the answers to his questions or this is a sort of game to entertain the SO community ;)

Andreas_D
Andreas_D: if it really is a game - somebody is having a great success in playing it - by catching those who wish to get a 'few more points' here and there by getting trivial questions answered again and again. :)
techzen
And that's why I checked 'community wiki' - one shouldn't increase reputiation through reacting on those questions ;)
Andreas_D