Java音符的枚举

时间:2012-11-03 04:25:38

标签: java enums

如何在Java中创建音符的枚举,每个音符都有一个八度音,然后是一个键控变量?这就是我到目前为止......

    public enum Notes
    {
            c,
            cS,
            d,
            dS,
            e,
            f,
            fS,
            g,
            gS,
            a,
            aS,
            b;
            int octave;
            boolean isPlaying;
    }

所以当我在代码中访问枚举时,我会写这样的东西......

Notes.c.octave = 4;
Notes.c.isPlaying = true;

现在我的问题是:如何为每个八度音阶中的每个音符设置一个isPlaying布尔值?

像这样:

Notes.c.octave.isPlaying = true;

或者我必须这样:

public enum Notes
{
        c1,
        cS1,
        d1,
        dS1,
        e1,
        f1,
        fS1,
        g1,
        gS1,
        a1,
        aS1,
        b1
        c2,
        cS2,
        d2,
        dS2,
        e2,
        f2,
        fS2,
        g2,
        gS2,
        a2,
        aS2,
        b2;

        etc...

        boolean isPlaying;
}

提前感谢您抽出宝贵时间回答这个问题!

6 个答案:

答案 0 :(得分:3)

您不应修改枚举字段!!!

原因是每个实例在JVM中都是唯一的(如单例),而使用相同注释的另一个线程将共享相同的playing字段,这是一个严重错误的设计。

此外,您的枚举应命名为单数Note,而不是复数Notes。原因应该是显而易见的:枚举的每个实例代表一个音符,而不是多个音符。


正确的方法是创建一个包含3个字段的类:

public class Tone {
    private Note note; 
    private int octave;
    private boolean playing;
    // with getters and setters
}

由于每个音符都可以是平的♭,锐♯,双平?和双锐?,我会使用这个更准确地反映现实的模型。此外,即使playing字段感觉错误。感觉更像是Tone应该是immutable而其他一些实体(例如Player)知道当前正在播放的Tones,所以我建议这样做:

public enum Note {
    C, D, E, F, G, A, B
}

public enum Shift {
    DoubleFlat, Flat, Natural, Sharp, DoubleSharp
}

public class Tone {
    private Note note; 
    private Shift shift; 
    private int octave;
    private int duration; // include a duration - perhaps milliseconds
    // with only getters, being immutable
}

public class Player {
    // has references to `Tones` and a way to schedule their being played
}

答案 1 :(得分:2)

你可以看看Manufaktura.Music图书馆:http://manufaktura-programow.pl/En

它包含步数,音高,节奏值,音阶等的对象模型。它在c#中,但语法类似于Java。

答案 2 :(得分:1)

我会移动到一个对象而不是一个枚举。您可以创建一个具有以下内容的对象JavaNote: 字符串说明; int octave; boolean isPlaying;

为什么要打扰枚举?

答案 3 :(得分:1)

创建枚举元素,默认octave变量为0isPlaying变量为false,如下所示:

  public enum Notes
  {
        c(0, false),
        cS(0, false),
        d(0, false),
        dS(0, false),
        e(0, false),
        f(0, false),
        fS(0, false),
        g(0, false),
        gS(0, false),
        a(0, false),
        aS(0, false),
        b(0, false);
        int octave;
        boolean isPlaying;

        Notes(int octave, boolean isPlaying){
            this.octave = octave;
            this.isPlaying = isPlaying;
        }

        int getOctave(){
            return this.octave;
        }

        boolean isPlaying(){
            return this.isPlaying;
        }
   }

现在您可以将枚举用作:

Notes.a.octave = 5;//assign the value if required
Notes.a.isPlaying = true;//assign the value if required
System.out.println(Notes.a.octave);//this will print 5
System.out.println(Notes.a.getOctave());//this will print 5
System.out.println(Notes.a.isPlaying);//this will print true
System.out.println(Notes.a.isPlaying());//this will print true

希望这有帮助!

答案 4 :(得分:1)

你不需要isPlaying标志去除那只存储Notes实例的实例并检查它。

Notes playingNote = Notes.c1;

当你必须检查播放音符时

 playingNote == Notes.c1

你只需要改变的是构造函数。声明采用Octave值的构造函数。

c1(1);
private int octave = 0;
private Notes(int octave){
        this.octave= octave;
}

注意:假设乐器的Octave不会改变。虽然不是乐器方面的专家。对于多个音符同时你可以使用EnumSet

答案 5 :(得分:0)

这是一个很好的问题!

我相信你的第一部分是正确的:

/** An enum of the valid note names */

public enum Note {
    c,
    cS,
    d,
    dS,
    e,
    f,
    fS,
    g,
    gS,
    a,
    aS,
    b;
}

您应该创建一个具有私有 octave isPlaying 属性的类以及 Note 枚举的实例。

也许你会得到这样的代码:

class InstrumentNote {
    private Note note;
    private int octave = 0;
    private boolean isPlyaing = false;

    public InstrumentNote(Note someNote, int someOctave) {
        note = someNote;
        octave = someOctave;
        isPlaying = false;
    }
}

class TestIt {
    public static void main(String[] args) {
        int octaveCount = 8; // big piano
        Set<Note> instrumentNotes = buildInstrument(octaveCount);
    }

    /** 
     *  Creates a Set of Notes.  A Set is used because each instrument
     *  should consist of a group of unique note instances, based on how
     *  many octaves it has.
     */

    public static Set<InstrumentNote> buildInstrument(int numOctaves) {
        Set<InstrumentNote> noteSet = new TreeSet<InstrumentNote>();
        for (int i = 0; i < numOctaves; i++) {
            for (Note n : Note.values()) {
               noteSet.add(new InstrumentNote(n, i, false));
            }
        }
        return noteSet;
    }


}

这是一个很好的问题,八度音是否应该成为枚举的一部分。

音符的八度音程不应该改变......但我认为它更适合作为同时具有Note实例的类的私有成员。

由于我不确定你的要求,我试图想象他们......

我设想您可以从一组有效的笔记中创建乐器歌曲(如上所示)。

这将为您提供各种灵活性:

  • 您可以创建一个具有一组备注
  • 的abstarct Instrument类
  • 你可以实现不同种类的乐器(小号一次只能弹奏一个音符,钢琴可以弹奏很多)
  • 你可以实现一首歌,这是一系列具有持续时间,音量,风格(断奏,连奏)等的音符......

如果您想要执行上述某些操作,您还需要一种方法对笔记进行排序(因此可以订购一组笔记)。

您可以使用比较器和/或名为 index order (或其他)的枚举属性来执行此操作。

我将继续写NoteComparator给你。

我不确定你是否可以使用枚举实现接口Comparable ...

希望其中一些准确或有帮助......