> -----Original Message-----
> From: Polar Humenn [mailto:[EMAIL PROTECTED] 
> Sent: 03 April 2007 22:52
> To: [email protected]
> Subject: Re: Checkstyle
> 
> 
> 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();
> }


Bits could be modelled as an inner interface within an outter Muffin
interface. So the "inner-ness" of Bits doesn't force Muffin to be a
class. 

But yeah, in general I agree that you don't always want to use an
interface. But most of the time in Java, the
concrete_class--extends-->abstract_class--implements-->interface pattern
works well.


> 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)?


Such name clashes are exactly why Java outlawed multiple class
inheritence.

AFAIK the reasoning is that this isn't an issue when implementing
multiple interfaces because there's no potentially different inherited
implementations of getManufacturer(). So the two getManufacturer()
methods can be treated as being the *same thing*.

But while Java allows multiple interface inheritence, it can't force you
to properly model the domain. In this case the correct relationship
between MyAppliance and Washer is probably composition as opposed to
inheritence. MyApplicance is-a Toaster, but MyApplicance is not a
Washer, rather its composed of a washer and a bunch of other stuff. So:

class MyAppliances implements Toaster {
    private Washer washer = new Washer() { 
       public String getManufacturer() {
          return "WasherCo";
       }
    }

    public String getManufacturer() {
       return "AcmeCrop";
    }

    public Washer getWasher() {
       return washer;
    }
}

So now myApp.getManufacturer() and myApp.getWasher().getManufacturer()
can return different values as expected.

Cheers,
Eoghan

> 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