Sign in to follow this  

Abstract classes

This topic is 4664 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

When you only care about how to interact with a class and not how it works. For example, my Bomberman clone has an abstract class for the AI. The class is implemented by a DLL. The game doesn't care how the AI works, just that it responds to certain events.
Another example is the DirectX interfaces. They're all abstract classes. You don't care how Direct3D draws a triangle, just that it does it.

Abstract classes come with a very minor overhead, so it's best not to use them everywhere, but there are some places where it's nessecary. If the class is to be implemented in another module (e.g. in a DLL), then you have to use an abstract class, otherwise you'll get compile errors when the compiler can't find the implementation for the class.

Share this post


Link to post
Share on other sites
If you use the microsoft specific keyword interface they come with no overhead as the vtable for the interface is not generated.

Interfaces are also useful for multiple inheritence. Some poeple don't like the baggage taht multiple inheritence adds for C++. With interfaces you can use multiple inheritence without the worries.

Note: pur virutal classes arent' the same as interfaces in that for pure virtual methods you can define some methods, with interfaces you can't as there is no vtable.

Cheers
Chris

Share this post


Link to post
Share on other sites
Code Complete, 2nd Edition
Chapter 6.1 - Class Foundations: Abstract Data Types (ATDs)
Page: 126

Buy this book. It's worth the money just for that sub-chapter alone. It's also one of the best books you'll find on software construction (i.e. making software :)).

Share this post


Link to post
Share on other sites
It helped me to relate abstract objects in programming to abstract objects in the real world. For example (Java code for ease of reading, though this applies to any OO language):
public abstract class Food {
//All food has flavor, but the Food class alone is too general to return a
//specific value
public abstract String getFlavor();
}

public class RegularPopcorn extends Food {
//RegularPopcorn is specific enough that we can return a flavor for it and
//implement the abstract method
public String getFlavor() {
return "Mmm. Salt and butter.";
}
}

public class Spinach extends Food {
//Spinach is also specific enough for us to return a flavor
public String getFlavor() {
return "Yuck, green nasty tasting ickyness.";
}
}

public abstract class Popsicle extends Food {
//Popsicle is more specific than Food, but there are many flavors of popsicle
//so we leave this class and its getFlavor method abstract
}

public class FudgeSicle extends Popsicle {
//Here's a more specific form of Popsicle that has a specific flavor we can return
public String getFlavor() {
return "Yum! Icy, chewy fudge melting in my mouth.";
}
}

Abstract methods (which are what make classes abstract) are like gaps in general object types whose implementation must be filled in by a more specific derived class. Like mentioned above, graphics and media devices are often abstract, because they can send output or receive input in different ways.

Another thing that comes to mind is streams. All streams can receive and/or send information from/to a buffer. Thus, a Stream class would have methods for reading and writing the stream. However, a file stream would do this very differently from a memory stream or a TCP socket stream, so the read and write methods are abstract and it's up to the deriving class to decide just how these operations should be accomplished.

Share this post


Link to post
Share on other sites
"Design Patterns: Elements of Reusable Software" by Erich Gamma, et. al.

Canonically payroll example. Some payrolls are done every week, some every two weeks, some are done twice a month. The common element is that people are paid according to a schedule, so that is what goes into the interface (the abc).


class IPaySchedule {
public:
virtual date NextPayDate(date today)=0;
virtual ~IPaySchedule() {}
};

class Weekly : IPaySchedule {
public:
virtual date NextPayDate(date today);
};

class BiWeekly : IPaySchedule {
public:
virtual date NextPayDate(date today);
};

class BiMonthly : IPaySchedule {
public:
virtual date NextPayDate(date today);
};


//From the configuration we decide which payschedule to create
std::string pay_schedule_desc = "BiWeekly";
IPaySchedule* pay_schedule = create_pay_schedule(pay_schedule_desc);
if( date::today() == pay_schedule->NextPayDate(date::today()) )
{//Time to pay people!
}



In the real-world you'd probably have sets of people who are paid at different schedules. And the NextPayDate algorithms would be complicated taking into account the configured holidays and weekends.

Share this post


Link to post
Share on other sites
You use them when you have an object A that needs to do something to a general objects of type B and don't care about specific types of the objects under B. Say you have a driver who knows how to work with a generic car steering interface and if there are various makes of cars but all cars implement the same steerable interface then the driver doesn't need to worry about how to specifically driver each car make.

Share this post


Link to post
Share on other sites

This topic is 4664 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this