Java 我应该在方法本身中调用set length方法吗?

Java 我应该在方法本身中调用set length方法吗?,java,Java,我的作业提示说明: 创建一个包含以下实例变量的MP3类:艺术家、歌曲、唱片集、曲目长度(以秒为单位)。提供一个包含四个参数、get/set方法和一个toString的构造函数。方法。toString方法应该返回一个带有MP3数据的字符串,并清楚地标记这些数据。在toString方法中,轨迹长度应转换为分和秒。例如,265秒将显示为4:25。请注意,MP3的曲目长度不能为零或负。将默认值1分钟用于无效的轨迹长度 我对这些指示的最后一句话感到困惑。有人能给我解释一下吗 到目前为止,我有以下代码: p

我的作业提示说明:

创建一个包含以下实例变量的MP3类:艺术家、歌曲、唱片集、曲目长度(以秒为单位)。提供一个包含四个参数、get/set方法和一个toString的构造函数。方法。toString方法应该返回一个带有MP3数据的字符串,并清楚地标记这些数据。在toString方法中,轨迹长度应转换为分和秒。例如,265秒将显示为4:25。请注意,MP3的曲目长度不能为零或负。将默认值1分钟用于无效的轨迹长度

我对这些指示的最后一句话感到困惑。有人能给我解释一下吗

到目前为止,我有以下代码:

public class MP3 {

    private String artist;
    private String song;
    private String album;
    private int trackLength;

    public MP3(String artistName, String songName, String albumName, int lengthOfTrack) {
        setArtist(artistName);
        setSong(songName);
        setAlbum(albumName);
        setLength(lengthOfTrack);
    }

    public void setArtist(String artistName) {
        artist = artistName;
    }

    public String getArtist() {
        return artist;
    }

    public void setSong(String songName) {
        song = songName;
    }

    public String getSong() {
        return song;
    }

    public void setAlbum(String albumName) {
        album = albumName;
    }

    public String getAlbum() {
        return album;
    }

    public void setLength(int lengthOfTrack) {
        trackLength = lengthOfTrack;

         if(getLength() <= 0) {
                setLength(60);
            }
    }

    public int getLength() {
        return trackLength;  
    }

    public String toString() {

        return String.format("%s, %s, %s, %d : %d",
            getArtist(), getSong(), getAlbum(),
            getLength() / 60, getLength() - (getLength() / 60) * 60); 
    } 
}
公共类MP3{
私人弦乐演奏家;
私人弦乐;
私人弦乐专辑;
私有整数轨道长度;
公共MP3(字符串艺人名称、字符串歌曲名称、字符串专辑名称、int lengthOfTrack){
setArtist(艺人姓名);
setSong(宋名);
setAlbum(albumName);
设置长度(长到机架);
}
public void setArtist(字符串artistName){
艺术家=艺术家姓名;
}
公共字符串getArtist(){
回归艺术家;
}
公共void setSong(字符串songName){
宋=宋名;
}
公共字符串getSong(){
返回歌曲;
}
public void setAlbum(字符串albumName){
相册=相册名称;
}
公共字符串getAlbum(){
返回相册;
}
公共无效设置长度(int lengthOfTrack){
轨道长度=轨道长度;

如果(getLength()否,在正常情况下,将导致递归,直到发生,而不是在您的情况下,因为在下一次调用时,您将退出递归。通常,如果不需要,您应该避免使用递归

您只需在设置之前修改该值,例如:

public void setLength(int trackLength) {
  if (trackLength <= 0)
    trackLength = 60;

  this.trackLength = trackLength;
} 
public void setLength(int trackLength){
如果(trackLength“使用一分钟的默认值表示无效的曲目长度”

如果你没有被告知音轨长度,它应该设置为60。所以

private int trackLength=60

然后,所有设置者都需要检查输入值是否为正值。与其他答案没有太大区别,真的

以下是我的看法:

  • 您确实正确地实现了需求(如中所示,它可以正常工作)
  • 但是,您的实现非常复杂,并且使用了错误的做法:在不需要时使用递归,从构造函数调用可重写的方法,将字段更改为无效值,然后立即更改
  • 忽略在构造函数/setter中传递的值并用默认值替换它也是一种不好的做法:应该抛出一个异常。但这是你的老师要求的,所以你对此无能为力
以下是我将如何实施它:

public class MP3 {

    private String artist;
    private String song;
    private String album;
    private int trackLength;

    public MP3(String artist, String song, String album, int trackLength) {
        this.artist = artist;
        this.song = song;
        this.album = album;
        this.trackLength = trackLengthOrDefault(trackLength);
    }

    public String getArtist() {
        return artist;
    }

    public void setArtist(String artist) {
        this.artist = artist;
    }

    public String getSong() {
        return song;
    }

    public void setSong(String song) {
        this.song = song;
    }

    public String getAlbum() {
        return album;
    }

    public void setAlbum(String album) {
        this.album = album;
    }

    public int getTrackLength() {
        return trackLength;
    }

    public void setTrackLength(int trackLength) {
        this.trackLength = trackLengthOrDefault(trackLength);
    }

    private int trackLengthOrDefault(int length) {
        return length <= 0 ? 60 : length;
    }

    public String toString() {
        return String.format("%s, %s, %s, %d:%d",
            artist, song, album, trackLength / 60, trackLength % 60);
    }
}
公共类MP3{
私人弦乐演奏家;
私人弦乐;
私人弦乐专辑;
私有整数轨道长度;
公共MP3(弦乐艺术家、弦乐歌曲、弦乐专辑、int trackLength){
这个艺术家=艺术家;
这首歌=这首歌;
this.album=相册;
this.trackLength=trackLength默认值(trackLength);
}
公共字符串getArtist(){
回归艺术家;
}
公共虚空设置艺术家(弦乐艺术家){
这个艺术家=艺术家;
}
公共字符串getSong(){
返回歌曲;
}
公歌(弦歌){
这首歌=这首歌;
}
公共字符串getAlbum(){
返回相册;
}
公共空集相册(字符串相册){
this.album=相册;
}
公共int getTrackLength(){
返回轨道长度;
}
public void setTrackLength(int trackLength){
this.trackLength=trackLength默认值(trackLength);
}
私有int-trackLength默认值(int-length){

返回长度我的意思是,你可以非递归地做,但这样做不是问题。好吧,考虑到你的代码,我认为你已经完全理解了它。为什么你认为你还没有理解呢?我认为这意味着“如果他们给你的音轨长度是垃圾(例如-0:37,0:00,或者哈哈),使用1:00”。哦,等等,你想使用
如果(lengthOfTrack@EliSadoff
getLength()
返回
trackLength
为什么它会导致StackOverflower错误?我不同意递归是可以避免的。递归可以是美妙而有效的,只要它是尾部递归。@EliSadoff:递归是一个工具,当你决定使用它时必须使用它,而不是作为你的代码的副作用,这显然是发生在h这是代码的副作用吗?此外,这不会导致
StackOverflowException
getLength()
是在检查之前设置的,所以一切正常。@EliSadoff:这是一个副作用,因为OP不想显式使用递归,只是碰巧使用了它,所以它是所有影响下的副作用。我并不反对递归,我完全知道它有多棒(以及如何用一堆代码来解决复杂的问题)但是,除非您知道自己为什么要这样做,否则设置一个调用自身的setter并不是一个好的做法。没有办法避免设置轨迹长度,因为唯一的构造函数将其作为参数。因此,将字段初始化为60是没有用的。@JBNizet如果(lengthOfTrack>0),您可以使用
if
in作为构造函数中的一个条件。OP已经间接地拥有了它,这是通过构造函数调用setter来实现的。我不会像OP那样编写代码,但他确实实现了句子要求的内容。仅仅将字段设置为60是没有用的,相反。@jbnize我不同意。我只是指出了一种你可以做到的方法理论上,在这种情况下使用默认字段值。@JBNizet您能解释一下我如何更直接地使用它吗?非常有用!谢谢。考虑到昨天是我第一天听说递归:)您将如何扩展语句
return