That of course is a simple example that works well with that pattern.
However, if I don't want the interface. If my abstract class carries other things that are specific to the class, but do not adhere to an interface very well, like having inner classes,

abstract class Muffin {
        class Bits { ... }

        abstract Bits getBits();
}

or common method name collisions:

Especially if you have interfaces like :

interface Toaster {
        String getManufacturer():
      .....
}

interface Washer {
       String getManufacturer();
       .....
}

and some developer decides he doesn't want separate classes:

class MyAppliances implements Toaster, Washer {
}

The compiler doesn't complain. (at least it didn't a while ago, is that still so)?


Cheers,
-Polar

Glynn, Eoghan wrote:
Remember Java, unlike C++, has interfaces as well as abstract classes.

So the typical Java idiom is more like:

interface Muffin {
    Kind kind();
}

abstract class AbstractMuffin implements Muffin {
    // common impl ...

    public abstract kind();
}

class BlueBerryMuffin extends AbstractMuffin { public Kind kind() {
        return Kind.BLUEBERRY;
    }
}

The key here is that parameter types and other interactions are all done
in terms of the interface type, Muffin.

So your objection in terms of method signature like eat(AbstractMuffin
m) goes away. In java this parameter would usually be of the interface
type, e.g. eat(Muffin m).


The misspelt method that was supposed to be overriding a default impl
can actually be compiler-enforced in Java, using the @Override
annotation [1].

So the following code:

class CornMuffin extends AbstractMuffin { @Override
    public Kind keind() {
        return Kind.CORN;
    }
}

will fail to compile.

/Eoghan

[1] http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Override.html

-----Original Message-----
From: Polar Humenn [mailto:[EMAIL PROTECTED] Sent: 03 April 2007 22:10
To: [email protected]
Subject: Checkstyle

Is there a "good" motivation of why "abstract" classes have to be named "Abstract" "Base" or "Factory"?

If a class is declared "abstract", I want the *compiler* to tell the developer that s/he has not filled out a particular functionality when s/he extends the abstract class. Not that I want it named "Abstract". For example,

abstract class Muffin {
     ......
     abstract Kind kind();
}

I really don't want my code littered with method definitions like:

      void eat(AbstractMuffin muff) {

I want it to be:

      void eat(Muffin muff);

because that's what it is. It's not an AbstractMuffin, it's a Muffin!

Can we get rid of that particular checkstyle rule?

I say that, because it forces, either

a) illogical names, like AbstractMuffin, to be used in definitions, making for
    awkwardness. (i.e. eat(AbstractMuffin muff);

b) default implementations, just to avoid the illogical names!

      This particular avoidance causes errors to be caught at run time
instead of compile time, where it should be caught! And sometimes causing
      a loss of time to find it.

For example, with the current checkstyle rule I could be forced to write the class with a default implementation expecting it to be overridden. (Except there is no way to tell a compiler that).

     class Muffin {
           .....
           Kind kind() {
                 return Kind.BLUEBERRY;
          }
      }

      void eat(Muffin muff) {
System.out.println("I'm eating a " + muff.kind() + " muffin!");
     }

and a developer goes ahead and writes:

       class CornMuffin extends Muffin {
            Kind kiend() {
                  return Kind.CORN;
            }
       }

and it compiles fine without problems. Subsequently he can't figure out why his application still says he has a BLUEBERRY muffin, especially when he has used "eat(new CornMuffin())".

This kind of pattern complete adverted the use of compiler protections.

Cheers,
-Polar




Reply via email to