views:

89

answers:

2

Hello everyone,

I am reading the book -- Hadoop: The Definitive Guide

In chapter 2 (Page 25), it is mentioned "The new API favors abstract class over interfaces, since these are easier to evolve. For example, you can add a method (with a default implementation) to an abstract class without breaking old implementations of the class". What does it mean (especially what means "breaking old implementations of the class")? Appreciate if anyone could show me a sample why from this perspective abstract class is better than interface?

thanks in advance, George

+6  A: 

If you add a method with a default implementation to an abstract class, nothing needs to change in any derived classes.

Alternatively, if you add a method to an interface, any classes implementing that interface need to implement the method - otherwise they will not compile.

Justin Ethier
Thanks! "nothing needs to change in any base classes" -- "any base classes", you mean the base class of the abstract class, or the class which derives from the abstract class?
George2
Damn. I should have just left those examples out. Took me four more minutes ;-)
Joey
Any answers to my comment above? :-)
George2
@George, Justin: I made a change hoping to make that part clear, as "base class" was the wrong term there (imo; or I might have understood something wrong there)
Joey
@George - I meant, a class derived from the abstract class does not need to change if a new method (with a default implementation) is added.
Justin Ethier
@Johannes - Thanks! FWIW, I thought my answer might be too brief. +1 to you since you fleshed it out in much more detail :)
Justin Ethier
On second thought I should have probably just provided an example for the case where the interface/base class is expanded and why that is causing a problem ... ah well, still learning how to write :)
Joey
" I meant, a class derived from the abstract class does not need to change if a new method (with a default implementation) is added." -- it makes senses, thank you!
George2
+8  A: 

In the case of an interface, all methods that are defined in an interface must be implemented by a class that implements it.

Given the interface A

interface A {
    public void foo();
}

and a class B:

class B implements A {
}

it has to provide an implementation for the method defined in the interface:

class B implements A {
    @Override
    public void foo() {
        System.out.println("foo");
    }
}

Otherwise it's a compile-time error. Now take an abstract class with a default implementation of a method:

abstract class C {
    public void bar() {
        System.out.println("bar");
    }
}

where a class inheriting from this abstract class can look like this:

class D extends C { }

without an error. But it can also override the default method implementation if it's inclined to do so.

What the author was saying there: If your API isn't stable yet and you need to adapt interfaces (yes, abstract classes are also interfaces (in OOP-speak)), then an abstract class allows you to add things without breaking classes that are already there. However, this only holds true for non-abstract methods. If you add abstract methods, then they still need to be implemented in every derived class. But still, it can make your life easier if you have an API that is still evolving and already lots of stuff building on it.

Joey
Thanks! What I am confusing is this statement -- "breaking old implementations of the class" in the book. "The class" means class derives from the abstract class, or class which abstract class is based on?
George2
@George: It means the class that derived from the old version of the interface/abstract class. With interfaces it is no longer valid as it fails to implement a method you added to the interface. With abstract classes and non-abstract methods it can just happily use the base class' implementation without even knowing that it's there.
Joey
Thanks! You mean suppose in version 1, the abstract class has method Foo and a class derives from the abstract class implements Foo. And in version 2 of abstract class, a new method Goo is added, and the derived class will still work without being impacted (if Goo has default implementation in abstract class)?
George2
@George: Exactly. While, if you had an interface (or would have made `Goo` abstract), you would have to go through *every* derived class and add a suitable implementation of the method.
Joey
Thanks, question answered!
George2
I might add that some people of the hardcore OOP crowd might point out that there are numerous techniques and patterns exist to avoid this kind of thing. While that may be true, the authors of Hadoop likely had valid reasons for not using them. For instance, design patterns often trade implementation complexity for flexibility. I have the great joy of working on a project where everything is a plugin and all things are kept as flexible as possible. It's a pain to work with because even simple things take a while to build. I do admit that patterns have a place but they can as well be overused.
Joey