Inheritance or condition? - language-agnostic

I've heard people saying that good design involves using inheritance instead of littering your code with if block. In what situation should we use inheritance, and when condition block is just fine?

One refactoring like this is called Replace Conditional With Polymorphism.
We actually favor composition over inheritance, but ... it's really too broad of a topic to discuss here, however the book is worth a read and can get you started.

Generally, it isn't good object-oriented programming practice to have code like the following:
var chioce = PAINT_SCREEN_BLUE
if (choice == PAINT_SCREEN_BLUE):
paintScreen(blue)
else if (choice == PAINT_SCREEN_RED):
paintScreen(red)
else if (choice == PAINT_SCREEN_GREEN):
paintScreen(green)
The above can utilize polymorphism to call some method that will perform the action that is abstracted away in related classes with a common ancestor:
interface ScreenPainter:
function perform()
class BlueScreenPainter implements ScreenPainter:
function perform():
paintScreen(blue)
...
// The conditional block can be replaced with the following call:
var choice = PAINT_SCREEN_BLUE
ScreenPainter p = Painters.getPainter(choice)
p.perform()
However, this practice definitely should not apply for all conditionals, however, when it comes to long switch blocks or if-elseif-else blocks, in many cases, use of inheritance will make your code more extensible and more robust.

If blocks (or switch blocks) that are used to decide what logic to do based on the type of an argument should be replaced with polymorphism.
If new features in a program will cause you to make additional case or else blocks use polymorphism.
If statements should be used for natural ordering type comparisons ( <, >, ==, etc.) or to check if something is null.

This is one of those questions that, while others can offer guidelines, the final answer for any particular situation is always, "it depends on the situation."
The best way to be able to develop the ability to answer it for any particular situation is to gain experience: i.e., experiment. Try both ways, where you can do so reasonably. (Obviously, you don't want to be flipping back and forth in situations where you have to change a thousand lines of code to do so.) Which worked better? Which felt better to you? Why?
Do this enough, and you'll soon reach the level of expertise where you no longer need the general advice, and people start asking you how you know what to do in any particular situation. (You won't be able to explain it; that's part of the nature of expertise. See The Dreyfus Model of Skill Acquisition for more details.

Here is something I ran into the other day
PHP is my language of choice
class Cache {
public function __construct($resource) {
// if statement to determine from type if it is a file, url or string. instead, change it to accept a string
}
}
or... it could of been extended
class cacheURL extends Cache {
public function __construct($url) {
$string = file_get_contents($url);
parent::__construct($string);
}
}
Rough example, but I hope you catch my drift....

In my opinion the two are not mutually exclusive. I typically use inheritance when I have 2 or more classes that have common functionality.

When to Use Inheritance from Microsoft
Composition vs. Inheritance in Java

Inheritance is better when some condition is checking something intrinsic to your object that you check constantly (like a state or type). In this example, it's an operator for a mathematical expression tree. An operator, like addition, has an expression before and after the plus sign (infix notation) so I call them left and right because it is represented as a tree. There are also unary operators like a hyphen that negates a value, but it only has one child expression.
Using inheritance means the type (simplified to just unary vs. binary) is factored into the inheritance:
class Operator
{
abstract string ToString();
}
class UnaryOperator : Operator
{
Expression Expression { get; }
override string ToString() {...}
}
class BinaryOperator : Operator
{
Expression LeftExpression { get; }
Expression RightExpression { get; }
}
class AdditionOperator : BinaryOperator
{
override string ToString()
{
return this.LeftExpression.ToString() + "+" + this.RightExpression.ToString();
}
}
As opposed to:
class Operator
{
Expression LeftExpression { get; }
Expression RightExpression { get; }
OperatorType Type { get; }
string ToString()
{
switch(this.Type)
{
case OperatorType.Addition:
return this.LeftExpression.ToString() + "+" + this.RightExpression.ToString();
case OperatorType.Negation:
return "-" + this.LeftExpression.ToString();
case ...:
}
}
}
enum OperatorType
{
// Unary operators
Negation,
// Binary operators
Addition,
Subtraction,
Multiplication
}
Here your Unary operator doesn't have a Left and a Right expression, just an expression. This means you have to introduce convention that Left is used and Right is null. ToString would have to check OperatorType; so would any other method that needs to act on what operator it is.
The latter approach is most often seen in XML DOM implementations where XmlNode is pretty much everything any XML node could contain...ever. It makes for some very confusing situations:
How can an attribute or text node have ChildNodes?
How can a document have ChildNodes when it can only have one? (It need not be a collection)
How can a document have a ParentNode?
How can a document have a Value?
Etc.

Related

Can a pure function call external function?

Can a pure function call an external method?
for example:
class Dog {
function jump(name) {
return "a dog named " + name + " jumped!"
}
function jumpTwice(names) {
var result = [];
for (var i = 0; i < 2; i++) {
result.push(jump(names[i]));
}
return result.join("\n");
}
}
can jumpTwice() be considered as a pure function?
When you can
A pure f function can call any other function/method g0...gn.
But g0...gn must be pure as well.
When you cannot
As soon as you get a pure function f and you invoke a non pure function g from within f, then f is no longer pure.
Yes, it is pure. It doesn't mutate any global state nor gives different results for same input.
In the specific case you give, yes. But what you have there is a method and methods require extra care.
Pure functions always give the same result for any given input, no matter what the current program state.. Methods can be viewed as functions which are passed their object as a hidden parameter. To be pure, the method must not access any implicit state (nor may they call any other methods/functions which are susceptible to implicit state). This means also not using any object fields which contain implicit state. The comments discussion hopefully gives an example of how to judge that context.
It's not enough to shun mutable fields - the value in immutable fields field must be knowable/predictable . For example, if an object contained an immutable private field which was given a random number on object creation, any method which used that value to compute it's output would be impure.
On the other hand, if your Dog class had an immutable name field which was set on object creation, then methods which used that field can be considered pure (unless something else disqualifies them).
EDIT
It would have been helpful to say that "side effect" and "purity" is contextual (as discussed in the comments). Which is what I didn't entirely clearly allude to by the use of the words "knowable" and "predictable". The comments discussion illustrates the importance of knowing the context.

How add custom behavior to copy function in case classes in scala?

Is it possible o add custom behavior to copy function in case classes?
Something like this:
case class User (version: Integer) { //other fields are omitted
//something like this
override def copy (...) {
return copy(version = version + 1, ...)
}
}
So I do not want to rewrite copy function, just add increasing version field and copy others. How can I do that?
Adding behavior to fundamental functions such as copy is not a good idea. The functional approach is to let data be just data, and to have the behavior in the functions that operate on the data from outside.
But if you really want to do it, you will just have to re-implement the copy method, like this:
case class User(name:String, age:Int, version:Int = 0) {
def copy(name:String = this.name, age:Int = this.age) = User(name,age,version+1)
}
Usage:
scala> User("John Doe", 25).copy(age = 26)
res4: User = User(John Doe,26,1)
But note that you will probably have to re-implement some other methods as well for useful behavior. For example, you might not want people to be able to pass a version when constructing a user. So you need to make the constructor private and add an apply method.
You also might not want the version field to be considered for equality. So you have to redefine equals and hashCode to omit the version field. So since you have redefined almost everything that a case class gives you, you might as well make the class a normal non-case class.
In general, I think case classes should be used for pure data, while more object oriented classes that mix data and logic are best done as normal classes, even if it means a bit more typing.

Method Parameter id similar to Class Field Best Practice?

I have some methods which their parameters are related to the fields, and have the same ids or similar ids.
Some programmming languages doesn't allow this, some do, which do you consider a "Best Practice" (for cross-language) ?
(The example is C++ alike, but apply to any progr. lang.)
Example:
public class AnyClass {
private string FilePath = "";
public void assignPath(string FilePath) { ... }; // <-- same as field member
public void assignPath(string AFilePath) { ... }; // <-- has a prefix
public void assignPath(string filePath) { ... }; // <-- different case
}
Cheers.
UPDATE: add "cross language"
One thing for sure. Don't use parameter names starting with capital letter. I haven't seen those as best practices in any language I know. Same for fields that are not public.
I like the third option in your example.
In general I believe "PascalCase" is used to denote static fields, and "camelCase" is used for instance fields. Also, as a general rule of thumb all method arguments should probably be "camelCase" or just "lower" if possible (I think a short truncation for a method argument is fine due to the limited scope).
However, I don't think having your method parameter arguments match exactly to instance field names is ideal in any situation. As far as prefixes go, any Hungarian notation should probably be avoided.

How should I design a method that allows for optional operations?

For example, suppose I this:
class Gundam00 extends Gundam implements MobileSuit {
...
public void fight(final List<MobileSuit> mobiruSuitso, final List<Gundam> theOtherDudes, final List<Person> casualities) {
....
}
}
Suppose theOtherDudes and casualities parameters are optional. How can I make this method as clean as possible? I thought about having booleans indicating if they're null, and then checking them as needed.
I could also have different versions of the method for each combination of parameters but there would be a lot of code duplication I think.
Any suggestions?
I find that past 2-3 arguments, the ability to remember what all the arguments to a function are suffers. And comprehensibility along with it.
Passing named arguments can help. Languages with a convenient hash-like literal syntax make this really easy. Take JavaScript:
g = new Gundam00();
g.fight({opponent: enemy, casualties: 'numerous'});
You can also take advantage of variable length argument features to work this in (treat odd arguments as names, even arguments as the actual parameters).
g.fight('opponent',enemy,'casualties', 'numerous');
And some languages actually support named arguments straight-out (see: http://en.wikipedia.org/wiki/Named_parameter#Use_in_programming_languages ).
Finally, you might want to consider adding other methods for this using what some call a Fluent Interface (http://en.wikipedia.org/wiki/Fluent_interface ). Basically, you've got method call which return the object itself, so you can chain calls together:
g.opponent(enemy).casualties('numerous').fight();
This might be the easiest option if you're working in a manifestly/statically-typed class-focused language.
Update
Responding to Setsuna's comment... in that last example, if you've got the luxury, you can make methods like opponent and casualties simple setters that don't affect any internal state or computation in any other way than setting a parameter for which they're named. They simply set internal properties up, and then all of the real work happens inside action methods like fight.
If you can't do that (or if you don't like writing methods whose operations are sub-atomic), you could stake out a half-way spot between this idea with the hash-like literal idea, and create your own collection class specifically for invoking named arguments:
n = new NArgs();
g.fight(n.arg('opponent',enemy).arg('casualties','numerous').arg('motion','slow'));
A little more unwieldy, but it separates out the named arguments problem and lets you keep your methods a bit more atomic, and NArgs is probably something you could implement pretty easily just wrapping some methods around one type of Collection (HashTable?) or another that's available in your language.
Add the methods. Overloading methods is generally an antipattern and a refactoring opportunity for someone else.
http://www.codinghorror.com/blog/2007/03/curlys-law-do-one-thing.html
I thought about having booleans indicating if they're null, and then checking them inside and reacting accordingly.
Or ... you could just check if they're null.
if(theOtherDudes == null)
...
If there is only one "main method" in your class, then you can implement the optional arguments as getter/setter functions. Example:
public void setOtherDudes(final List<Gundam> theOtherDudes) {} // for input arguments
public List<Person> getCasualities() {} // for output arguments
And then, in your documentation, mention that if the caller has any optional input arguments it has to be passed in before calling fight(), and the optional output values will be available when fight() has been called.
This is worthwhile if there are dozens of optional arguments. Otherwise, I suggest overloading the method as the simplest way.

Try to describe polymorphism as easy as you can [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
How can polymorphism be described in an easy-to-understand way?
We can find a lot of information about the subject on the Internet and books, like in Type polymorphism. But let's try to make it as simple as we can.
Two objects respond to the same message with different behaviors; the sender doesn't have to care.
Every Can with a simple pop lid opens the same way.
As a human, you know that you can Open() any such can you find.
When opened, not all cans behave the same way. Some contain nuts, some contain fake snakes that pop out. The result depends on what TYPE of can, if the can was a "CanOfNuts" or a "CanOfSnakes", but this has no bearing on HOW you open it. You just know that you may open any Can, and will get some sort of result that is decided based on what type of Can it was that you opened.
pUnlabledCan->Open(); //might give nuts, might give snakes. We don't know till we call it
Open() has a generic return type of "Contents" (or we might decide no return type), so that open always has the same function signature.
You, the human, are the user/caller.
Open() is the virtual/polymorphic function.
"Can" is the abstract base class.
CanOfNuts and CanOfSnakes are the polymorphic children of the "Can" class.
Every Can may be opened, but what specifically it does and what specific tye of contents it returns are defined by what sort of can it is.
All that you know when you see pUnlabledCan is that you may Open() it, and it will return the contents. Any other behaviors (such as popping snakes in your face) are decided by the specific Can.
This is from my answer from a similiar question. Here's an example of polymorphism in pseudo-C#/Java:
class Animal
{
abstract string MakeNoise ();
}
class Cat : Animal {
string MakeNoise () {
return "Meow";
}
}
class Dog : Animal {
string MakeNoise () {
return "Bark";
}
}
Main () {
Animal animal = Zoo.GetAnimal ();
Console.WriteLine (animal.MakeNoise ());
}
The Main() method doesn't know the type of the animal and depends on a particular implementation's behavior of the MakeNoise() method.
The simplest description of polymorphism is that it is a way to reduce if/switch statements.
It also has the benefit of allowing you to extend your if/switch statements (or other people's ones) without modifying existing classes.
For example consider the Stream class in .NET. Without polymorphism it would be a single massive class where each method implements a switch statement something like:
public class Stream
{
public int Read(byte[] buffer, int offset, int count)
{
if (this.mode == "file")
{
// behave like a file stream
}
else if (this.mode == "network")
{
// behave like a network stream
}
else // etc.
}
}
Instead we allow the runtime to do the switching for us in a more efficient way, by automatically choosing the implementation based on the concrete type (FileStream, NetworkStream), e.g.
public class FileStream : Stream
{
public override int Read(byte[] buffer, int offset, int count)
{
// behave like a file stream
}
}
public class NetworkStream : Stream
{
public override int Read(byte[] buffer, int offset, int count)
{
// behave like a network stream
}
}
Poly: many
Morphism: forms / shapes
The Actor vs. the Character (or Role)
Apples and oranges are both fruit. Fruit can be eaten. Hence, both apples and oranges can be eaten.
The kicker? You eat them differently! You peel the oranges, but not the apples.
So the implementation differs, but the end result is the same, you eat the fruit.
If it walks like a duck and quacks like a duck, then you can treat it as a duck anywhere you need a duck.
This is a better article actually
Polymorphism allows Objects to "Look" the same, but behave in different ways. The usual example is to take an animal base class with a Speak() Method, A dog subclass would emit a Bark whereas a Pig subclass would emit an oink.
The 5 second short answer most people use so other developers can get their head around Polymorphism is overloading and overriding
Same syntax, different semantics.
Simplest way to describe it: a verb that can apply to more than one kind of object.
Everything else, as Hillel said, is just commentary.
Polymorphism is treating things abstractly by relying on knowledge of a common "parent" (think heirarchies like Animal as a parent of Dogs and Cats).
For example, all Animals can breathe oxygen, and while they may each do this differently you could design a facility that provides oxygen for Animals to breathe, supporting both Dogs and Cats.
As a little extra, you can do this even though Animal is an "abstract" identifier (there is no real "Animal" thing, just types of Animals).
Polymorphism is the storing of values of more than one type in a location of a single type.
Note that most of the other answers to this question, at the time of my writing, are actually describing dynamic dispatch, not polymorphism.
Dynamic dispatch requires polymorphism, but the reverse is not true. One could imagine a language very similar to Java or C# but whose System.Object had no members; typecasting would be necessary before doing anything with the value. In this notional language, there would be polymorphism, but not necessarily virtual methods, or any other dynamic dispatch mechanisms.
Dynamic dispatch is the related but distinct concept, well enough described in most of the other answers. However, the way it normally works in object-oriented languages (selecting a function based on the first ('this' or 'Self') argument type) is not the only way it can work. Multiple dispatch is also possible, where the selection is applied across the types of all the arguments.
Similarly, overload resolution and multiple dispatch are exact analogues of one another; overload resolution is multiple dispatch applied to static types, while multiple dispatch is overload resolution applied to runtime types stored in polymorphic locations.
Polymorphism is dividing the world into boxes based on common properties and treating the items in a given box as interchangeable when you only want to use these common properties.
Polymorphism is the ability to treat different things as if they were the same thing by establishing a shared identity between them then exploiting it.
Polymorphism is what you get when the same method applies to multiple classes. For example, both a String and a List might have "Reverse" methods. Both methods have the same name ("Reverse"). Both methods do something very similar (reverse all the characters or reverse the order of the elements in the list). But the implementation of each "Reverse" method is different and specific to its class. (In other words, the String reverses itself like a string, and the List reverses itself like a list.)
To use a metaphor, you could say "Make Dinner" to a French chef or to a Japanese chef. Each would perform "make dinner" in their own characteristic way.
The practical result is that you could create a "Reversing Engine" that accepts an object and calls "Reverse" on it. As long as the object has a Reverse method, your Reversing Engine will work.
To extend the chef analogy, you could build a "Waiterbot" that tells chefs to "Make Dinner". The Waiterbot doesn't have to know what type of dinner is going to be made. It doesn't even have to make sure it's talking to a chef. All that matters is that the "chef" (or fireman, or vending machine, or pet food dispenser) knows what to do when it's told to "Make Dinner".
What this buys you as a programmer is fewer lines of code and either type-safety or late binding. For example here's an example with type safety and early binding (in a c-like language that I'm making up as I go):
class BankAccount {
void SubtractMonthlyFee
}
class CheckingAccount : BankAccount {}
class SavingsAccount : BankAccount {}
AssessFee(BankAccount acct) {
// This will work for any class derived from
// BankAccount; even classes that don't exist yet
acct.SubtractMonthlyFee
}
main() {
CheckingAccount chkAcct;
SavingsAccount saveAcct;
// both lines will compile, because both accounts
// derive from "BankAccount". If you try to pass in
// an object that doesn't, it won't compile, EVEN
// if the object has a "SubtractMonthlyFee" method.
AssessFee(chkAcct);
AssessFee(saveAcct);
}
Here's an example with no type safety but with late binding:
class DatabaseConnection {
void ReleaseResources
}
class FileHandle {
void ReleaseResources
}
FreeMemory(Object obj) {
// This will work for any class that has a
// "ReleaseResources" method (assuming all
// classes are ultimately derived from Object.
obj.ReleaseResources
}
main() {
DatabaseConnection dbConn;
FileHandle fh;
// You can pass in anything at all and it will
// compile just fine. But if you pass in an
// object that doesn't have a "ReleaseResources"
// method you'll get a run-time error.
FreeMemory(dbConn);
FreeMemory(fh);
FreeMemory(acct); //FAIL! (but not until run-time)
}
For an excellent example, look at the .NET ToString() method. All classes have it because all classes are derived from the Object class. But each class can implement ToString() in a way that makes sense for itself.
EDIT: Simple != short, IMHO
Polymorphism is language functionality allowing high-level algorithmic code to operate unchanged on multiple types of data.
This is done by ensuring the operations invoke the right implementation for each data type. Even in an OOP context (as per this question's tag), this "right implementation" may be resolved at compile-time or run-time (if your language supports both). In some languages like C++, compiler-supplied support for run-time polymorphism (i.e. virtual dispatch) is specific to OOP, whereas other types of polymorphism can also operate on data types that aren't objects (i.e. not struct or class instances, but may be builtin types like int or double).
( The types of polymorphism C++ supports are listed and contrasted in my answer: Polymorphism in c++ - even if you program other languages, it's potentially instructive )
The way I try and think of it is something that looks the same but can have different functionality depending on the instance. So you can have a type
interface IJobLoader
but depending on how it is used can have different functionality while still looking the same. You may have instances for BatchJobLoader, NightlyJobLoader etc
Maybe I am way off.
The term polymorphism can also apply to overloading functions. For example,
string MyFunc(ClassA anA);
string MyFunc(ClassB aB);
is a non-object oriented example of polymorphism.
Is the ability that objects have to respond to the same message in different ways.
For instance , in languages such as smalltalk, Ruby, Objective-C, you just have to send the message and they will respond.
dao = XmlDao.createNewInstance() #obj 1
dao.save( data )
dao = RdbDao.createNewnewInstance() #obj 2
dao.save( data )
In this example two different objects, responded in different ways to the same messages: "createNewInstance() and save( obj )"
They act in different ways, to the same message. In the above languages, the classes might not even be in the same class hierarchy, it is enough that they respond to the message.
In languages such as Java, C++, C# etc. In order to assign the object to an object reference, they must share the same type hierarchy either by implementing the interface or by being subclass of a common class.
easy .. and simple.
Polymorphism is by far, the most important and relevant feature of object oriented programming.
It is a way to treat different things that can do something something similar in the same way without caring how they do it.
Let's say you have a game with a bunch of different types of Vehicles driving around such as Car, Truck, Skateboard, Airplane, etc... They all can Stop, but each Vehicle stops in a different way. Some Vehicles may need to shift down gears, and some may be able to come to a cold stop. Polymophism lets you do this
foreach (Vehicle v in Game.Vehicles)
{
v.Stop();
}
The way that stop is implemented is deferred to the different Vehicles so your program doesn't have to care about it.
It's just a way to get old cold to call new code. You write some application that accepts some "Shape" interface with methods that others must implement (example - getArea). If someone comes up with a new whiz-bang way to implement that interface your old code can call that new code via the the getArea method.
The ability of an object of some type (e.g. a car) to act (e.g. brake) like one of another type (e.g. a vehicle) which usually suggests common ancestry (e.g. car is a subtype of vehicle) at one point in the type hierarchy.
Polymorphism is the Object Oriented solution to problem of passing a function to another function. In C you can do
void h() { float x=3.0; printf("%f", x); }
void k() { int y=5; printf("%i", y); }
void g(void (*f)()) { f(); }
g(h); // output 3.0
g(k); // output 5
In C things get complicated if the function depends on additional parameters. If the functions h and k depend on different types of parameters you are in trouble and you must use casting. You have to store those parameters in a data structure, and pass a pointer to that data structure to g which passes it to h or k. h and k cast the pointer into a pointer to the proper structure and unpack the data. Very messy and very unsafe because of possible casting errors:
void h(void *a) { float* x=(float*)a; printf("%f",*x); }
void k(void *a) { int* y=(int*)a; printf("%i",*y); }
void g(void (*f)(void *a),void *a) { f(a); }
float x=3.0;
int y=5;
g(h,&x); // output x
g(k,&y); // output y
So they invented polymorphism. h and k are promoted to classes and the actual functions to methods, the parameters are member variables of the respective class, h or k. Instead of passing the function around, you pass an instance of the class that contains the function you want. The instance contains its own parameters.
class Base { virtual public void call()=0; }
class H : public Base { float x; public void call() { printf("%f",x);} } h;
class K : public Base { int y; public void call() { printf("%i",y);} } k;
void g(Base &f) { f.call(); };
h.x=3.0;
k.y=5;
g(h); // output h.x
g(k); // output k.x