所以我编写了一些代码,这些代码涉及扩展我之前编写过的类,其中的文件是使用构造函数创建和命名的,该构造函数的名称和类型为long。在那个原始类中,我在构造函数中验证了输入的文件名包含一个"。"字符但不需要对文件进行特定扩展。对于我正在编写的这个新类,我要求名称的扩展名是" .mp3"。但是,我的编译器不喜欢超级构造函数之前的验证。
这是我目前的代码:
public class Song extends DigitalMedia{
private String artist;
private String album;
private String name;
private long size;
public Song(String aName, long aSize, String aArtist, String aAlbum){
super(aName, aSize);
setArtist(aArtist);
setAlbum(aAlbum);
}
有没有办法验证" aName"包含" .mp3"在我创建该构造函数之前?
答案 0 :(得分:3)
我不能说它是否是设计程序的最佳方式,但您可以在super
个参数中调用验证器方法:
public Song(String aName, long aSize, String aArtist, String aAlbum){
super(validateName(aName), aSize);
setArtist(aArtist);
setAlbum(aAlbum);
}
private static String validateName(String name) {
if (whatever) {
throw new Whatever();
}
return name;
}
答案 1 :(得分:2)
到达constructor
的代码执行意味着该对象处于活动状态,现在可以初始化其states
(字段)。
类A.java
的对象也可以被称为A.java
的超类对象。在类A.java
初始化状态之前,对象继承超类的属性和特性是有道理的。在超类进行初始化之后,类A.java
有机会进行初始化。
如果超类中存在无参数构造函数,则隐式调用超类的构造函数,否则需要显式调用超类的任何一个参数化构造函数。
如果条件在constructor
失败,您希望做什么?您可以选择抛出异常,但仍然创建了对象,您可以通过覆盖finalize()
方法并检查this
对象来验证它。您可能希望通过调用System.gc()
来影响垃圾回收器,以便更快地到达finalize()
方法执行代码。
建议的解决方案
您应该在调用构造函数之前验证构造函数的参数。如果要将其封装在类中,则可以选择添加非私有静态方法(您可能希望将其命名为getInstance()
)创建并返回类Song
的对象。在这种情况下,您可以将构造函数设置为私有。请注意,这将使您的类不可扩展,它只是一个设计选择。
答案 2 :(得分:1)
另一种解决方案是通过内置类型检查来强制执行规则。
您可以创建MediaFormat
:
interface MediaFormat { }
实现MusicFormat
的{{1}},允许您指定支持的音乐格式:
MediaFormat
enum MusicFormat implements MediaFormat {
MP3("mp3");
private final String format;
MusicFormat(String format) {
this.format = format;
}
@Override
public String toString() {
return format;
}
}
可以由DigitalMedia
:
MediaFormat
class DigitalMedia {
private final MediaFormat format;
private final String name;
public DigitalMedia(String name, MediaFormat format) {
this.name = name;
this.format = format;
}
}
可以接受Song
:
MusicFormat
这将强制用户使用class Song {
public Song(String name, MusicFormat format) {
super(name, format);
}
}
中指定的任何内容,避免所有那些讨厌的检查。然后,您可以公开返回MusicFormat
String
方法
答案 3 :(得分:0)
从继承角度来看,一个子类不应该比它的超级类更具限制性。
但是如果你想让子类的实例化受到更多限制,你可以创建构造函数[1,3,5]
并提供一个首先进行验证的工厂方法。
private
您可以使用封装来强制执行不变量,而不是限制类型本身。