Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

This question is regarding a homework project in my first Java programming class (online program).

The assignment is to create a "stringed instrument" class using (among other things) an array of String names representing instrument string names ("A", "E", etc). The idea for the 12-string is beyond the scope of the assignment (it doesn't have to be included at all) but now that I've thought of it, I want to figure out how to make it work.

Part of me feels like the 12-String should have its own class, but another part of me feels that it should be in the guitar class because it's a guitar. I suppose this will become clear as I progress but I thought I would see what kind of response I get here.

Also, why would they ask for a String[] for the instrument string names? Seems like a char[] makes more sense.

Thank you for any insight.

Here's my code so far (it's a work in progress):

public class Guitar {


private int numberOfStrings = 6;
private static int numberOfGuitars = 0;
private String[] stringNotes = {"E", "A", "D", "G", "B", "A"};
private boolean tuned = false;
private boolean playing = false;

public Guitar(){
    numberOfGuitars++;
}

public Guitar(boolean twelveString){
    if(twelveString){
        stringNotes[0] = "E, E";
        stringNotes[1] = "A, A";
        stringNotes[2] = "D, D";
        stringNotes[3] = "G, G";
        stringNotes[4] = "B, B";
        stringNotes[5] = "E, E";
        numberOfStrings = 12;
    }
}

public int getNumberOfStrings() {
    return numberOfStrings;
}

public void setNumberOfStrings(int strings) {
    if(strings == 12 || strings == 6) {
        if(strings == 12){
            stringNotes[0] = "E, E";
            stringNotes[1] = "A, A";
            stringNotes[2] = "D, D";
            stringNotes[3] = "G, G";
            stringNotes[4] = "B, B";
            stringNotes[5] = "E, E";
            numberOfStrings = strings;
        }
        if(strings == 6)
            numberOfStrings = strings;
    }//if
    else
        System.out.println("***ERROR***Guitar can only have 6 or 12 strings***ERROR***");
}

public void getStringNotes() {
        for(int i = 0; i < stringNotes.length; i++){
            if(i == stringNotes.length - 1)
                System.out.println(stringNotes[i]);
            else
                System.out.print(stringNotes[i] + ", ");
        }//for
}
share|improve this question
4  
To model stringed instruments, you should be prepared to handle any number of courses of strings with any number of strings in each course. (E.g., a regular six-string guitar would be six courses of one string each.) You also can't declare that guitars are six- or 12-stringed beasts because there exist seven- and eight-string guitars as well as variants like tenor and plectrum guitars, which have four. –  Blrfl Dec 12 '12 at 3:58
1  
Some part of me wonders whether the idea to model objects having strings with strings was a test, or just from someone with a punny sense of humor. Also, to answer your question about String[] vs. char[] maybe because you could tune the string up or down a half step to flats or sharps? –  NickC Dec 12 '12 at 4:15
    
Blrfl: For the purposes of this assignment I'm limiting it to 6 and 12. NickC: Believe me, I had the same punny thought! I'm still trying to figure out how modeling real world items (like instruments) is going to translate into real life programming. Like I said, I'm hoping all will be clear as I progress. Thanks –  MayNotBe Dec 12 '12 at 4:49
    
How about using Int to represent the string, via the frequency? Like the A above middle C being stored as "440". That way, you can indicate WHICH "A" the string is. This is important because some guitar string configurations (Nashville Chickin' Pickin', for example) use different strings (banjo) for the guitar, but they are tuned to the same note, just an octave up. This will help your 12-string example too, since "D, D" implies that those notes are the same, which they AREN'T on some 12-strings. –  Graham Dec 12 '12 at 13:04
1  
@Graham: Frequencies won't work. You can tune a guitar to a' = 440 Hz, but a' = 443 Hz is equally valid; the strings are conceptually still tuned the same way, but none of the pitches match anymore. Further, guitar tuning isn't as straightforward as it appears, due to the small differences between pure fifths (2:3 frequency ratio) and tempered fifths (7 semitone steps based on 12 equal steps per octave). Hence, if a' is given as 440 Hz, e'' may be 660 Hz (pure), but a tempered tuning yields about 659.25 Hz. –  tdammers Dec 12 '12 at 20:36
show 2 more comments

2 Answers 2

The design decisions such as the one you mention should be driven by the requirements. Since it seems purely a modelling exercise, you shouldn't worry too much.

As a general rule for less future headaches, favour inmutable classes, so I would get rid of that setter.

I'd also use enums instead of char arrays.

Finally try not repeating chunks of code. That's just increasing the likelihood of bugs and makes it harder to understand the code.

Ah, and don't forget to document your code: what does a method do, preconditions, postconditions, exceptions.

share|improve this answer
    
Jubbat: Thank you. Now I get to look up enums and immutable classes and that's exactly why I posted! Makes sense getting rid of the setter - it wasn't part of the assignment either. re: the repeats - I also need to look up if I can call methods from methods in a class (if that makes sense) As far as documentation - I tend to write the code and then go through it leaving comments. Should I get used to commenting as I go? Also, I haven't learned exceptions yet - but I'm dying to get there already so I can start verifying user input. Thanks again! –  MayNotBe Dec 12 '12 at 4:38
1  
FYI, I see NO reason to add documentation to the code above. The methods and variables are nicely named, indicating what they do. You should put 'why' you did something in comments if its a requirement reason that isn't immediately obvious in the code. But don't just repeat the method name for the sake of documenting. –  Graham Dec 12 '12 at 13:09
1  
@Graham In regards to documentation, some professors expect an unrealistic amount of commenting and will influence their grades based on it. I don't know what the case is for our OP here, though. That may have just been the college I went to. –  KChaloux Dec 12 '12 at 13:38
    
@MayNotBe No problem, glad to help. Consider also taking a look at code review for questions about code style and such. –  Jubbat Dec 12 '12 at 15:11
    
Hi folks, documentation seems pretty important to my professor so I'll end up going comment crazy. I checked out Enums and even created one for the "strings" (complete with frequency values!) but manipulating it was beyond my skillset at this point. –  MayNotBe Dec 13 '12 at 2:08
show 3 more comments

This goes a bit beyond an intro Java class, but...

Subclassing can send you down some pretty deep rabbit holes. The number of strings is only the beginning. Acoustic, electric, or acoustic-electric hybrid? If electric, solid or hollow body? How many pickups? Single or double coil (humbuckers)? Fixed or floating bridge? If acoustic, classical or steel string (classicals have a wider neck and use nylon strings)? And on and on and on. Creating a separate class or subclass for every type of guitar quickly leads to madness (and we haven't even gotten into basses or other types of stringed instruments).

Instead of trying to track all that information by creating a bunch of subclasses of Guitar, a better approach is to delegate tracking that information to other classes. For example, we can create a Tuning class which tracks the number of strings (or courses, thanks Blrfl) and their tunings. We can create a Body class that tracks whether it's a solid or hollow body, a Pickup class to track the type of pickup, a Neck class to describe the width, radius, and scale length of the neck, etc. We then compose all of these separate classes into a Guitar class1:

public class Guitar {
  Body bodyStyle;
  Neck neckStyle;
  Tuning tuning;
  ...
};

Note that each of these classes may also delegate some information to other classes (for instance, the Tuning class could delegate tracking information about individual guitar strings (gauge (thickness), wound/unwound, composition, etc.) to a GuitarString class.

This way, we can use the same Guitar class to specify many different types of guitars:

Guitar g = new Guitar(new Body (/* body parameters */),
                      new Neck (/* neck parameters */),
                      new Tuning (/* tuning parameters */),
                      ...);

In general, you want to keep your class hierarchies pretty shallow, and use delegation as much as possible (when you hear or read someone say "favor composition over inheritance", this is what they mean). This gives you more flexibility and reduces your maintenance headaches.

Knowing where to draw the line is a matter of experience and the problem at hand. It's possible to go overboard either way. There are times where you want to subclass because you want to enforce a specific interface or behavior on all instances, and there are times where the effort of delegating to another class isn't worth it.


1: It's been over a year since I've had to write any Java, so I can't write any really detailed examples without screwing something up

share|improve this answer
    
Guitar's members could be interfaces. Guitar would then be constructed by newing implementations. A classic case of dependency injection. –  Brian Dec 12 '12 at 18:47
    
@Brian: true. I've been in C++ mode for the last year or so, so I wasn't thinking in terms of interfaces. –  John Bode Dec 12 '12 at 20:17
    
@JohnBode: You're not kidding about rabbit holes!! This is just an introductory Java class and it's a fairly simple assignment - but I keep thinking about new and fun directions to take it and, unfortunately, most of the destinations are far beyond my skill level. If you read my comments above, I think I ended up doing what you're suggesting here - it makes the most sense and let's each instrument stay in it's own class with it's different configurations. Thanks! –  MayNotBe Dec 13 '12 at 2:22
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.