3

您将如何在 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;
}

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

4

6 回答 6

4

你不应该修改你的枚举字段!!!

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

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


正确的方法是创建一个具有 3 个字段的类:

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

由于每个音符都可以降♭,升♯,双降

于 2012-11-03T05:14:06.867 回答
2

您可以查看 Manufaktura.Music 库: http: //manufaktura-programow.pl/En

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

于 2015-07-23T20:44:40.320 回答
1

你不需要isPlaying标志摆脱那个只是存储实例的Notes实例并检查它。

Notes playingNote = Notes.c1;

当你必须检查演奏音符时

 playingNote == Notes.c1

您只需要更改的是构造函数。声明接受 Octave 值的构造函数。

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

注意:假设乐器的八度没有改变。虽然不是乐器专家。对于同时多个音符,您可以使用 EnumSet

于 2012-11-03T04:38:33.103 回答
1

我会移动到一个对象而不是一个枚举。您可以创建一个对象 JavaNote,它具有: String note; 整数八度;boolean isPlaying;

为什么要打扰枚举?

于 2012-11-03T04:28:41.547 回答
1

octave使用默认变量 as0isPlaying变量创建枚举元素,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

希望这可以帮助!

于 2012-11-03T04:30:51.203 回答
0

这是一个很好的问题!

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

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

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

您应该创建一个具有私有octaveisPlaying属性的类以及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 实例的类的私有成员。

由于我不确定您的要求,因此我试图想象它们...

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

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

  • 您可以创建一个具有一组注释的抽象仪器类
  • 您可以实现不同种类的乐器(小号一次只能演奏一个音符,钢琴可以演奏多个)
  • 你可以实现一首歌曲,它是一系列具有持续时间、音量、风格(断奏、连奏)等的音符......

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

您可以使用 Comparator 和/或名为indexorder(或其他东西)的枚举属性来执行此操作。

我将把编写NoteComparator的练习留给你。

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

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

于 2012-11-03T04:54:50.600 回答