Differencebetween a Concrete Class and an Abstract Class

What is the difference between a concrete class and an abstract class?

An abstract class is a class for which one or more methods are declared but not defined, meaning that the compiler knows these methods are part of the class, but not what code to execute for that method. These are called abstract methods. Here is an example of an abstract class.

class shape {
public:
virtual void draw() = 0;
};

This declares an abstract class which specifies that any descendants of the class should implement the draw method if the class is to be concrete. You cannot instantiate this class because it is abstract, after all, the compiler wouldn't know what code to execute if you called member draw. So you can not do the following:

shape my_shape();
my_shape.draw();

To be able to actually use the draw method you would need to derive classes from this abstract class, which do implement the draw method, making the classes concrete:

class circle : public shape {
public:
circle(int x, int y, int radius) {
/* set up the circle */
}
virtual draw() {
/* do stuff to draw the circle */
}
};

class rectangle : public shape {
public:
rectangle(int min_x, int min_y, int max_x, int max_y) {
/* set up rectangle */
}
virtual draw() {
/* do stuff to draw the rectangle */
}
};

Now you can instantiate the concrete objects circle and rectangle and use their draw methods:

circle my_circle(40, 30, 10);
rectangle my_rectangle(20, 10, 50, 15);
my_circle.draw();
my_rectangle.draw();

Now of course the question is, why would you want to do this? Couldn't you just as well have defined the circle and rectangle classes and have done away with the whole shape class? You could, but then you wouldn't be able to take advantage of their inheritance:

std::vector<shape*> my_scene;
my_scene.push_back(new circle(40, 30, 10));
my_scene.push_back(new rectangle(20, 10, 50, 15));
std::for_each(my_scene.begin(), my_scene.end(), std::mem_fun_ref(&shape::draw)

This code let's you collect all your shapes into one container. This makes it a lot easier if you have a lot of shapes and many different shapes in your scene. For example we can now draw all the shapes in one go, and the code that does so doesn't even need to know about the different types of shapes we have.

Now finally we need to know why the draw function of shape is abstract, and not just an empty function, i.e. why didn't we just define:

class shape {
public:
virtual void draw() {
/* do nothing */
}
};

The reason for this is that we don't really want objects of type shape, they wouldn't be real things anyway, they would be abstract. So it doesn't make any sense to define an implementation for the draw method, even an empty one. Making the shape class abstract prevents us from mistakenly instantiating the shape class, or mistakenly calling the empty draw function of the base class instead of the draw function of the derived classes. In effect we define an interface for any class that would like to behave like a shape, we say that any such class should have a draw method that looks like we have specified it should.

To answer you last question, there isn't any such thing as a 'normal derived class' every class is either abstract or concrete. A class that has any abstract methods is abstract, any class that doesn't is concrete. It's just a way to differentiate the two types of classes. A base class can be either abstract or concrete and a derived class can be either abstract or concrete:

class abstract_base {
public:
virtual void abstract_method1() = 0;
virtual void abstract_method2() = 0;
};

class concrete_base {
public:
void concrete_method1() {
/* do something */
}
};

class abstract_derived1 : public abstract_base {
public:
virtual void abstract_method3() = 0;
};

class abstract_derived2 : public concrete_base {
public:
virtual void abstract_method3() = 0;
};

class abstract_derived3 : public abstract_base {
public:
virtual abstract_method1() {
/* do something */
}
/* note that we do not provide an implementation for
abstract_method2 so the class is still abstract */
};

class concrete_derived1 : public concrete_base {
public:
void concrete_method2() {
/* do something */
}
};

class concrete_derived2 : public abstract_base {
public:
virtual void abstract_method1() {
/* do something */
}
virtual void abstract_method2() {
/* do something */
}
/* This class is now concrete because no abstract methods remain */
};

Abstract class vs Concrete class?

If you have an object which mustn't get instantiated you should use an abstract class. A concrete class, though, should be used if you want to instantiate this class.

Imagine you want several animal classes. But the rule is just to instantiate specific animals like a dog, cat or a mouse. But now all of those animals share some properties and methods - like a name. So you put them in a base class Animal to avoid code duplication. You can't create an instance of Animal though:

public abstract class Animal
{
public string Name { get; set; }
public void Sleep()
{
// sleep
}
}

public class Cat : Animal
{
public void Meow()
{
// meooooow
}
}

public void DoSomething()
{
var animal = new Animal(); // illegal operation
var cat = new Cat(); // works fine
}

Difference between Concrete class and Abstract class in Objective-C

There is nothing to stop a person from instantiating a abstract class. There is no distinction between concrete and abstract classes.

A concrete class is one that is actually used "as is" for some purpose. A abstract class is a class that is subclassed but has little functionality on it's own. Example NSObject is a abstract class(never use it as is). UIActivityIndicator is a concrete class(pretty much always use it as is).

The only difference is that concrete classes are ready out of the box, and abstract classes are meant to be subclassed class.

Differences between abstract and concrete classes in inheritance, constructors, etc

Abstract class is, for the most part, a design concept. It does more for the readers of your code than it does for the compiler. The compiler and JVM support required for them is minimal: it boils down to setting a "do not instantiate me" flag on the class, and checking it when compiling the code and when trying to create an instance through reflection.

Benefits to human readers of your code, on the other hand, are much bigger: they know that you designed your abstract class for inheritance, and see what extension points you made for them through abstract methods. In addition, the compiler will track for them if they have provided overrides for all abstract methods.

How is abstract class different from concrete class?

Abstract classes cannot be instantiated directly. Declaring a class as abstract means that you do not want it to be instantiated and that the class can only be inherited. You are imposing a rule in your code.

If you extend your Parent/Child relationship example further to include a Person class then it would make good sense for Person to be abstract. Parent is a concrete idea and so is child. Person is an abstract concept in reality as well as in code.

One benefit is that you explicitly define and protect the idea of the abstract class. When you declare a class as an abstract there's no way that you or anyone else using your code uses it incorrectly by instantiating it. This reasoning is similar to why we specify functions and fields as public, private or protected. If you declare a function or member as private you are in effect protecting it from improper access from client code. Privates are meant to be used within the class and that's it. Abstract classes are meant to be inherited and that's that.

Now, do you have to use abstract classes and define functions and fields as private instead of public? No, you don't. But these concepts are provided to help keep code clean and well-organized. The abstract class is implemented in all object-oriented languages to my knowledge. If you look around you will see that C++, C#, VB.NET etc. all use this concept.

A better, specific example:

Shape hierarchy UML Diagram

In the example above the Shape class should be abstract because it is not useful on its own.

java - unique difference between abstract class and concrete class

The reason to use abstract class in this situation is to force everyone inheriting your base class to override the abstract doInit method. Without the class and the method being abstract, they may forget to do so, and the compiler would not catch them.

In addition to this pragmatic purpose, abstract classes provide a powerful way to communicate your design idea to the readers of your code. An abstract class tells the reader that the methods inside provide some common implementation for a group of related classes, rather than implementing a single concept that you are modeling. Very often communicating your intent to your readers is as important as it is to write correct code, because otherwise they might break something while maintaining your code.

It is customary in Java to call abstract classes Abstract...; in your example that would be AbstractParent.

Abstract Base Class vs. Concrete Class as a SuperType

If you need specific methods to be implemented, then use an Interface. If there is shared logic that can be pulled out, use an abstract base class. If the base set of functionality is complete on its own, then you can use a concreate class as the base. An abstract base class, and an Interface cannot be instantiated directly, and that is one of the advantages. If you can use a concrete type, then you need to do override methods, and that has a "code smell" to it.

Abstract class with all concrete methods

Well you could be using a template method pattern where there are multiple override points that all have default implementations but where the combined default implementations by themselves are not legal - any functional implementation must subclass.

(And yes, I dislike the template method pattern ;))



Related Topics



Leave a reply



Submit