• Create Account

### #ActualServant of the Lord

Posted 09 October 2012 - 07:21 PM

Inheritance almost always uses composition. The inherited class has to be composed (composition) of something, unless it's just functions.

Also, usually the derived class adds more than just the inherited class' variables, so any derived class is almost always inheriting and​ composing (again: unless it's just adding functions).

Example:
//This class is composition only, even though other classes inherit it.
class BaseClass
{
//Composition:
std::string stuff;
int moreStuff;
MyStruct otherStuff;
};

//This class has inheritance AND composition.
class DerivedA : public BaseClass
{
//Composition:
};

//Functions don't typically count as composition, so this class is inheritance only.
class DerivedB : public BaseClass
{
void myFunc();
};

In the code above, BaseClass is only using composition, but not inheritance. DerivedA is using both composition and inheritance. DerivedB is only using inheritance (since it doesn't add any member variables).

This class uses neither inheritance nor composition:
class ClassWithFunctionsOnly
{
void myFunc();
void myOtherFunc();
};
(Arguably, that class would be better off as functions within a namespace instead of a class - but it could legitimately be an abstract base class if one or more functions were virtual)

Yes, the primary pro of inheritance is polymorphism. The cons really start showing up when people go inheritance-crazy (defaulting to inheritance instead of defaulting to composition), and end up creating dozens upon dozens of abstract classes that aren't really needed by their program.
Abstract classes are classes that cannot be used themselves but define the common interface for other classes to use, for polymorphism. One of the goals of programmers is to make most of your code re-usable. This is good. However, in the quest to make code re-usable, many programmers get carried away with creating overly generic solutions that aren't really needed, and don't bring them closer to completing their project.

In the big picture, programming happens in layers. Each layer of code helps hone down from the generic (libraries, engines, and frameworks) to the specific (your project). If the code you are writing is too generic, it'll just be another layer of code between the libraries and your end-goal, without actually carrying you further towards that goal. When abstract programming goes too far, you end up just creating another framework ontop of whatever you are already using, thinking you are making your game, but really just making the unneeded framework that you'll eventually actually build your game upon... if you ever complete it, now that you wasted so much time accomplishing the nothing-framework that looks like something impressive.

There's an important balance between creating generic code that can be reused in other projects and creating specific code that actually furthers your current project.

### #2Servant of the Lord

Posted 09 October 2012 - 07:21 PM

Inheritance almost always uses composition. The inherited class has to be composed (composition) of something, unless it's just functions.

Also, usually the derived class adds more than just the inherited class' variables, so any derived class is almost always inheriting and​ composing (again: unless it's just adding functions).

Example:
//This class is composition only, even though other classes inherit it.
class BaseClass
{
//Composition:
std::string stuff;
int moreStuff;
MyStruct otherStuff;
};

//This class has inheritance AND composition.
class DerivedA : public BaseClass
{
//Composition:
};

//Functions don't typically count as composition, so this class is inheritance only.
class DerivedB : public BaseClass
{
void myFunc();
};

In the code above, BaseClass is only using composition, but not inheritance. DerivedA is using both composition and inheritance. DerivedB is only using inheritance (since it doesn't add any member variables).

This class uses neither inheritance nor composition:
class ClassWithFunctionsOnly
{
void myFunc();
void myOtherFunc();
};
(Arguably, that class would be better off as functions within a namespace instead of a class - but it could legitimately be an abstract base class if one or more functions were virtual)

Yes, the primary pro of inheritance is polymorphism. The cons are when people go inheritance-crazy (defaulting to inheritance instead of defaulting to composition), and end up creating dozens upon dozens of abstract classes that aren't really needed by their program.
Abstract classes are classes that cannot be used themselves but define the common interface for other classes to use, for polymorphism. One of the goals of programmers is to make most of your code re-usable. This is good. However, in the quest to make code re-usable, many programmers get carried away with creating overly generic solutions that aren't really needed, and don't bring them closer to completing their project.

In the big picture, programming happens in layers. Each layer of code helps hone down from the generic (libraries, engines, and frameworks) to the specific (your project). If the code you are writing is too generic, it'll just be another layer of code between the libraries and your end-goal, without actually carrying you further towards that goal. When abstract programming goes too far, you end up just creating another framework ontop of whatever you are already using, thinking you are making your game, but really just making the unneeded framework that you'll eventually actually build your game upon... if you ever complete it, now that you wasted so much time accomplishing the nothing-framework that looks like something impressive.

There's an important balance between creating generic code that can be reused in other projects and creating specific code that actually furthers your current project.

### #1Servant of the Lord

Posted 09 October 2012 - 07:20 PM

Inheritance almost always uses composition. The inherited class has to be composed (composition) of something, unless it's just functions.

Also, usually the derived class adds more than just the inherited class' variables, so any derived class is almost always inheriting and​ composing (again: unless it's just adding functions).

Example:
[class]//This class is composition only, even though other classes inherit it.
class BaseClass
{
//Composition:
std::string stuff;
int moreStuff;
MyStruct otherStuff;
};

//This class has inheritance AND composition.
class DerivedA : public BaseClass
{
//Composition:
};

//Functions don't typically count as composition, so this class is inheritance only.
class DerivedB : public BaseClass
{
void myFunc();
};[/code]

In the code above, BaseClass is only using composition, but not inheritance. DerivedA is using both composition and inheritance. DerivedB is only using inheritance (since it doesn't add any member variables).

This class uses neither inheritance nor composition:
class ClassWithFunctionsOnly
{
void myFunc();
void myOtherFunc();
};
(Arguably, that class would be better off as functions within a namespace instead of a class - but it could legitimately be an abstract base class if one or more functions were virtual)

Yes, the primary pro of inheritance is polymorphism. The cons are when people go inheritance-crazy (defaulting to inheritance instead of defaulting to composition), and end up creating dozens upon dozens of abstract classes that aren't really needed by their program.
Abstract classes are classes that cannot be used themselves but define the common interface for other classes to use, for polymorphism. One of the goals of programmers is to make most of your code re-usable. This is good. However, in the quest to make code re-usable, many programmers get carried away with creating overly generic solutions that aren't really needed, and don't bring them closer to completing their project.

In the big picture, programming happens in layers. Each layer of code helps hone down from the generic (libraries, engines, and frameworks) to the specific (your project). If the code you are writing is too generic, it'll just be another layer of code between the libraries and your end-goal, without actually carrying you further towards that goal. When abstract programming goes too far, you end up just creating another framework ontop of whatever you are already using, thinking you are making your game, but really just making the unneeded framework that you'll eventually actually build your game upon... if you ever complete it, now that you wasted so much time accomplishing the nothing-framework that looks like something impressive.

There's an important balance between creating generic code that can be reused in other projects and creating specific code that actually furthers your current project.

PARTNERS