如何在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;
}
提前感谢您抽出宝贵时间回答这个问题!
答案 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
变量为0
,isPlaying
变量为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实例的类的私有成员。
由于我不确定你的要求,我试图想象他们......
我设想您可以从一组有效的笔记中创建乐器或歌曲(如上所示)。
这将为您提供各种灵活性:
如果您想要执行上述某些操作,您还需要一种方法对笔记进行排序(因此可以订购一组笔记)。
您可以使用比较器和/或名为 index 或 order (或其他)的枚举属性来执行此操作。
我将继续写NoteComparator给你。
我不确定你是否可以使用枚举实现接口Comparable ...
希望其中一些准确或有帮助......