【问题标题】:Should I be calling the set length method in the method itself?我应该在方法本身中调用 set length 方法吗?
【发布时间】:2016-11-30 22:23:33
【问题描述】:

我的作业提示状态:

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

我对这些说明的最后一句话感到困惑。谁能给我解释一下?

到目前为止我有这个代码:

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); 
    } 
}

【问题讨论】:

  • 我的意思是,您可以非递归地执行此操作,但这样做没有问题。
  • 好吧,鉴于您的代码,我想您已经完全理解了。为什么你认为你没有?
  • 我将其理解为“如果他们给你的曲目长度是垃圾(例如 -0:37、0:00 或哈哈),请使用 1:00”。
  • 哦等等,你想使用if(lengthOfTrack &lt;= 0)而不是if(getLength() &lt;= 0)
  • @EliSadoff getLength() 返回trackLength

标签: java


【解决方案1】:

不,在正常情况下会导致递归直到发生StackOverflowException,而不是在您的情况下,因为在下一次调用时您将退出递归。一般来说,如果你不需要做,你应该避免使用递归。

您可以在设置之前简单地修改该值,例如:

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

  this.trackLength = trackLength;
} 

【讨论】:

  • 为什么会导致 StackOverflowError?
  • 我不同意要避免递归。只要是尾递归的,递归就可以是美妙而高效的。
  • @EliSadoff:递归是你决定使用它时必须使用的工具,而不是作为代码的副作用,这显然是这里发生的事情。
  • 代码的副作用是什么?此外,这不会导致StackOverflowExceptiongetLength() 在检查之前设置,所以一切正常。
  • @EliSadoff:这是一个副作用,因为 OP 不想显式使用递归,它恰好被使用,所以它是所有效果下的副作用。我不反对递归,我完全知道它有多棒(以及如何在一堆代码中解决复杂的问题),但是拥有一个调用自身的 setter 并不是一个好习惯,除非你知道你为什么这样做它。
【解决方案2】:

这是我的看法:

  • 您确实正确地实现了要求(如,它有效)
  • 不过,您的实现很复杂,并且使用了不好的做法:在不需要时使用递归、从构造函数调用可覆盖的方法、将字段更改为无效值,然后立即更改
  • 忽略在构造函数/设置器中传递的值并将其替换为默认值也是不好的做法:应该抛出异常。但这是你老师要求的,所以你无能为力。

这是我将如何实现它:

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);
    }
}

【讨论】:

  • 非常有帮助!谢谢你。考虑到昨天是我听说递归的第一天:)
  • 你将如何扩展声明return length &lt;= 0 ? 60 : length;
  • 如果长度
【解决方案3】:

“对无效的曲目长度使用一分钟的默认值”

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

private int trackLength = 60;

那么你所有的setter都需要检查传入的值是否为正。与其他答案没有太大区别,真的

【讨论】:

  • 没有办法避免设置轨道长度,因为唯一的构造函数将它作为参数。所以将字段初始化为 60 是没用的。
  • @JBNizet 您可以将if (lengthOfTrack &gt; 0) 作为构造函数中的条件。
  • OP 已经间接地拥有它,通过将它放在构造函数调用的 setter 中。我不会以与 OP 相同的方式对其进行编码,但他确实实现了句子所要求的内容。相反,将字段设置为 60 也无济于事。
  • @JBNizet 我同意。我只是指出一种在这种情况下理论上可以使用默认字段值的方法。
  • @JBNizet 你能解释一下我怎样才能更直接地做到这一点吗?
猜你喜欢
  • 2012-01-24
  • 1970-01-01
  • 2011-11-05
  • 2020-03-03
  • 2014-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多