Java转换接口,但使用对象方法

时间:2017-05-03 12:31:51

标签: java interface casting

我有一个关于如何在通过接口实例化时调用对象基本成员的问题。

假设我在我正在尝试构建的框架中具有以下接口和具体类:

public interface UsedClass {
    public boolean getBool();
}

public class User implements UsedClass {

    private String userName;
    private String userRole;
    public User(String userName, String userRole){
       this.userName = userName;
       this.userRole = userRole;
     }
    public boolean getBool() {
        // some code
    }
    public int getUserName() {
        return userName;
    }
    public int getUserRole() {
        return userRole;
    }

实施班:

public class Run implements UsedClass {        
    private String runName;
    private int runNumber;
    public Run(String runName, int runNumber){
       this.runName = runName;
       this.runNumber = runNumber;
     }
    public boolean getBool() {
        // some code
    }
    public String getRunName() {
        return runName;
    }
    public int getRunNumber() {
        return runNumber;
    }
}

但我无法将方法getRunName()getUserRole()放入界面!

最终目标是创建一个FactoryClass来处理从数据库GUI传递的对象。

我想知道是否有更好的方法然后使用类引用能够安全地调用Run或User的方法,例如:

public class EntityFactory {
  public static Object getValueAt(int rowIndex, int columnIndex, UsedClass usedClass) {
        if (usedClass.getClass().getSimpleName().equals("User")) {

            switch (columnIndex) {
            case 0:
                return ((User) usedClass).getUserName();
            case 1:
                return ((User) usedClass).getUserRole();
            default:
                return null;
            }
        } else if (usedClass.getClass().getSimpleName().equals("Run")) {
            switch (columnIndex) {
            case 0:
                return ((Run) usedClass).getRunName();
            case 1:
                return ((Run) usedClass).getRunNumber();
            default:
                return null;
    }
}

我已阅读了几篇SO帖子 type casting when objects are of interface references in JavaJava cast interface to class

暗示不建议引用转换,但由于我不能将所有方法都放入接口,会建议什么?

3 个答案:

答案 0 :(得分:1)

您应该使用instanceof而不是查看班级的simpleName

除此之外你是对的。您需要有一个包含公共方法的接口,然后您可以在其中调用它们,或者您需要确定该对象是特定类的实例,然后执行转换并进行方法调用。

您可以考虑使用Map<Class<? extends UsedClass>, Map<Integer, Function<___>>>处理程序。

然后你的处理将是

handlers.get(usedClass.getClass()).get(columnIndex).apply(usedClass);

显然你会想要考虑如何处理意外的类/索引案例。内部Map<Integer,...可能是List<...>,具体取决于它的使用方式。

答案 1 :(得分:1)

两件事:

  • 如果有的话,您使用 instanceof 而不是字符串/类名比较
  • 您将接口/类构建为有用。它们是您正在做的所有事情的基础。如果你从破碎的抽象开始,你就会破碎。就这么简单。

我的意思是:如果有共同的&#34;行为;然后你应该用常用的界面来表达。如果没有,你就可以在已经破裂的基础上开始你的努力;并且您将需要创建&#34;创造性的解决方法&#34;到处都是为了对抗那种疾病的症状

也许一个小的解决方案可能是至少有多个接口,比如

interface UsedClass { ...

interface SpecialUsedClassA extends UsedClass { ...

interface SpecialUsedClassB extends UsedClass { ...

比你至少可以返回UsedClass而不是Object。

答案 2 :(得分:1)

static interface ColumnSource<T> {
    String getColumn(T value, int index);
}
static Map<Class, ColumnSource> map = new HashMap();
static {
    map.put(User.class, new UserNameAndRoleSource<User>() {
        public String getColumn(User user, int index) { 
            switch (index) {
                case 0: return user.getUserName(); 
                case 1: return user.getUserRole(); 
                default: throw new RuntimeException();
            }
        }
    });
    map.put(Run.class, new ColumnSource<Run>() {
        public String getColumn(Run run, int index) { 
            switch (index) {
                case 0: return run.getRunName(); 
                case 1: return run.getRunNumer();
                default: throw new RuntimeException();
            }
        }
    });
}
public static Object getValueAt(int rowIndex, int columnIndex, Object o) {
   Class type = o.getClass();
   ColumnSource source = map.get(type);
   if (source == null) throw new RuntimeException(type.getName() + " not supported"); 
   return source.getColumn(o, columnIndex);
}