tags:

views:

209

answers:

6

I'm new to programming and have some questions about classes.

I'll use Karel as an example:

public class Karel extends robot{
   ....

}

then I extend Karel:

public class SuperKarel extends Karel{
   ....

}

but then I want to organize some groups of methods:

public class KarelJumps extends SuperKarel {
    ....

}

public class KarelColor extends SuperKarel {
    ....

}

But then if I want to make Karel jump I have to create an instance of KarelJumps rather the SuperKarel. But because KarelJumps is a different object then KarelColor I couldn't use any of its methods.

So would I just put all of the KarelJumps and KarelColor methods inside SuperKarel? Do I just make one large object?

+1  A: 

If you want a Karel that jumps and has access to KarelColor methods, you will need to put them in a single class, or change the hierarchy.

KarelJumps and KarelColor are siblings, and cannot access one another's methods. If you really want to keep them separate, maybe:

public class SuperKarel extends Karel
public class KarelJumps extends SuperKarel
public class KarelColor extends KarelJumps

EDIT: Listen to ChrisB's answer, though. If you're not adding significant functionality with each extending class, you probably should avoid the hierarchy.

pianoman
+4  A: 

The most useful reason for extending a class is so that you can use the underlying class's functionality in new objects, and then add behaviors and characteristics that are unique to the new type. If there are no compelling reasons for doing so, and very often there are not, then don't do it. Don't overcomplicate your design, just to try to make use of polymorphism and inheritance.

You want to use these techniques to make your applications less complex not more so. For a new programmer, I would recommend that you get the book "Code Complete" and make it your Bible for a while. You will not learn a language from it per se, but you will learn how things should be done and why that is.

Chrisb
A: 

I think you are overlooking the concept of methods. Classes are structures that can contain data and define methods. In order to have an action performed, you do not need to continue to extend the original class, you can define new methods. Extending Karel is fine, as long as there is a reason why you need to do something in your SuperKarel that is similar but different from something Karel does.

public class Karel extends robot{
    public void jump(){
    ...
    } 

   public void setColor(Color c) {
   ...
   }

}

public class SuperKarel extends Karel{
    public void jump(){
       //jump in a super way    
    } 

   public void setColor(Color c) {
       //set some super color 
   }
}
akf
A: 

Whenever you create a class ask "what does it do?" The methods go in the class.

You need to look first from the perspective of the person using your Karel.

Here is myK he is a Karel

oh, I wonder what he can do ... hmmm looks like a Karel can jump

myK.jump(howHigh)

hey he jumped

wonder what else he can do ...

What that person doesn't want is plethora of different object myK, mySuperK, myColouredK to do different jobs. You give him a nice coherent and complete Karel object.

If you feel that this results in a very big "Karel" class, and you want further organisation then you may decompose the Karel implementation (think wheels, pens etc) to do the various tasks, but from the outside it's a Karel.

djna
+2  A: 

It looks like you're trying to understand polymorphism more than classes.

Inheritance doesn't provide a mechanism of "method grouping."

The core concept of classic inheritance and polymorphism is conveniently captured in the Liskov Substitution Principle. Stolen from that wiki page:

if S is a subtype of T, then objects of type T in a program may be replaced with objects of type S without altering any of the desirable properties of that program.

Ensure that your sub-classes are substitutable for the super classes and that they add some significant, appropriate functionality besides, otherwise don't use inheritance.

Greg D
A: 

There are several solutions:

  1. You can move the methods up in the class tree (as you already know).

  2. You can use an interface to declare the common methods. If KarelJumps and KarelColor implement the interface, some code can ask for an "implementation of this interface". Since both classes implement (satisfy) the interface, the code will work. The drawback: You must implement the methods for the interface in each class (code duplication -> bad).

  3. Java doesn't support "mixins", so this is not an option but for completeness: Mixins are pieces of code which the compiler copies around for you. So you get a single place where you can maintain the code and then have the compiler copy said code into thousands of places (or use any other trick to make it look like it did).

  4. You can use a delegate. The delegate then implements the method. In the two Karel classes, you add a field delegate and call the delegate implementation:

    interface IDelegate { void method (); }
    class Delegate implements IDelegate {
        void method () { ... }
    }
    
    
    public class KarelJumps extends SuperKarel implements IDelegate {
        IDelegate delegate = new Delegate ();
    
    
    
    // Instead of copying the code, delegate the work
    void method () { delegate.method (); }
    
    }
Aaron Digulla