我有一个抽象的Paper
类,其中包含所有论文的常用属性以及一个或多个子类别的纸张,这些类别为该类纸张添加了附加信息。然后我有HashMap<String, Paper>
来存储多篇论文。
我的应用程序允许用户通过提供pid
然后提供要更新的属性和值来更新论文。我遇到的问题是,当我拥有的是超类时,如何更新子类的属性。
处理这种情况的最佳方式/做法是什么?
public abstract class Paper {
String pid;
String title;
String author;
}
public class Publication extends Paper {
int pages;
}
public class PHDThesis extends Paper {
String supervisor;
}
这是我目前拥有的**,它使用instance of
;但我觉得应该有更好的方法来做到这一点。
import java.util.*;
public class App {
public static abstract class Paper {
private String title;
private String author;
public Paper(String title, String author) {
this.title = title;
this.author = author;
}
public void update(String title, String author) {
this.title = title;
this.author = author;
}
}
public static class Publication extends Paper {
private int pages;
public Publication(int pages, String title, String author) {
super(title, author);
this.pages = pages;
}
public void update(String title, String author, int pages) {
super.update(title, author);
this.pages = pages;
}
}
public static class PHDThesis extends Paper {
private String supervisor;
public PHDThesis(String supervisor, String title, String author) {
super(title, author);
this.supervisor = supervisor;
}
public void update(String title, String author, String supervisor) {
super.update(title, author);
this.supervisor = supervisor;
}
}
public static void main(String[] args) {
HashMap<String, Paper> papers = new HashMap<String, Paper>();
papers.put("P001", new PHDThesis("My Super", "My PHD Title", "My Author"));
papers.put("P002", new Publication(22, "My Pub Title", "My Author"));
Paper p = papers.get("P001");
if (p instanceof PHDThesis) {
((PHDThesis)p).update("New Title", "New author", "New Super");
} else if (p instanceof Publication) {
((Publication)p).update("New Title", "New author", 33);
}
}
}
**减少了测试代码,实际代码更复杂,布局更好。
答案 0 :(得分:3)
您可以使用每个属性的getter创建一个名为UpdateBundle的对象。
然后Paper类将有一个方法更新(UpdateBundle),每个孩子将以不同的方式实现。
您所要做的就是为每个孩子调用该方法,他们将知道如何处理它。
另外,我不明白纸质课为什么是抽象的。你似乎没有抽象的方法。
public abstract class Paper {
String pid;
String title;
String author;
public void update(PaperUpdateBundle bundle)
{
pid = bundle.getPID();
title = budnle.getTitle();
author = bundle.getAuthor();
}
}
public class Publication extends Paper {
int pages;
public void update(PaperUpdateBundle bundle)
{
super.update(bundle);
pages = bundle.getPages();
}
}
public class PHDThesis {
String supervisor;
public void update(PaperUpdateBundle bundle)
{
super.update(bundle);
supervisor = bundle.getSupervisor();
}
}
public interface PaperUpdateBundle
{
String getPID();
String getTitle();
String getAuthor();
int getPages();
String getSupervisor();
}
答案 1 :(得分:2)
创建方法
public void update( Map<String, Object> parameters );
到所有论文并从Paper实现中提取相关属性。
在出版物中,它可能看起来像:
public void update( Map<String, Object> parameters ) {
super.update( parameters );
this.pages = parameters.get( "pages" );
}
答案 2 :(得分:2)
我在很久以前就问了类似的问题,这个问题的答案可能对你有帮助,
祝你好运!答案 3 :(得分:0)
接受答案的问题是它要求您手动更新所有属性。如果属性列表发生更改,则必须更改update()方法,否则事情将不同步。根据我的经验,这经常发生。然后你必须花很多时间来追踪这个错误。
另一种方式(我不会称之为“更好”的方式)是使用反射或某些第三方库来复制字段。但是,有一些权衡。优点是您的代码需要的工作少得多,而且(可能)会有更少的错误。缺点是您的代码将更慢,更不灵活,并且缺乏编译时检查。
我有时使用Jackson的ObjectMapper.convertValue()来做到这一点。您可以在此处找到其他方法:Copy all values from fields in one class to another through reflection。