无法实现继承的抽象方法

时间:2013-12-05 20:52:43

标签: java interface

这个想法是从SSO类调用带有MyCredentials实例的方法登录。最终结果是MyCredentials将在MyAuthentication中可用。

问题:由于接口需要一个Credentials实例,而我正在尝试发送MyCredentials实例,因此MyAuthentication会产生错误。我现在还不太清楚该做什么。

目前有几种接口身份验证的实现。我无法改变它。我注定了吗?

public class Credentials{
     public Credentials(){
          ...   
     }
}

public class MyCredentials extends Credentials{

    public MyCredentials(){
         super();
         //extend Credentials here
    }
}

public interface Authentication{
    public User createUser(Credentials c){
        ...
    }
}

public class MyAuthentication implements Authentication{

    public User createUser(MyCredentials c){
        ...
    }
}

public class Context{

    ...

    //This was there already
    public login(String login, String password){
        Manager.get(new Credentials(login, password));
            //at some point, interacts with MyAuthentication
    }

    //I added this
    public login(MyCredentials c){
        Manager.get(c);
            //at some point, interacts with MyAuthentication
    }
}

public class SSO{
     Context ctx;

    public do(){
        MyCredentials c = new MyCredentials();
        ctx.login(c);       
    }
}

更新#1

当实现必须处理Credentials和MyCredentials时会发生什么?

我应该遵循与Context类相同的方法,并使用不同的类复制方法吗?或者有更好的方法吗?

public interface Manager<T extends Credentials> {

    Repository get(T credentials) throws RepositoryException;
}

public class LocalManager implements Manager {
    public Repository get(final Credentials credentials) throws Exception {
            AuthenticatedUser user = userAuthenticator.authenticate(credentials);
            return new RepositoryImpl(commonRepository, user);
        }

    //Add this new method?
    public Repository get(final MyCredentials credentials) throws Exception {
            AuthenticatedUser user = userAuthenticator.authenticate(credentials);
            return new RepositoryImpl(commonRepository, user);
        }

}

更新#2

即使这两种方法具有不同的签名,它始终是凭据凭据触发的方法....

2 个答案:

答案 0 :(得分:4)

利用仿制药的力量

interface Authentication<T extends Credentials> {
    public User createUser(T c);
}


class MyAuthentication implements Authentication<MyCredentials> {

    @Override
    public User createUser(MyCredentials c) {
        // ...
    }
}

类型参数T可以是Credentials或其任何子类型。您的实现将指定其中之一。作为一种类型论证。

答案 1 :(得分:1)

你没有注定要失败。界面看起来很好。

我认为您需要做的是更改MyAuthentication的实现。您需要一个覆盖接口中方法的方法(具有相同的签名)。例如:

public class MyAuthentication implements Authentication{

    public User createUser(Credentials c)
    {
      if(c instancof MyCredentials)
      {
        MyCredentials myCredentials = (MyCredentials)c;
        createUser(myCredentials);
      }
      else
      {
        throw new RuntimeException("This implementation only handles Credentials of type MyCredentials");
      }
    }

    public User createUser(MyCredentials c){
        ...
    }
}