Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/383.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java-泛化不同的类、类似的方法(不改变子类?)_Java_Generics_Composition - Fatal编程技术网

Java-泛化不同的类、类似的方法(不改变子类?)

Java-泛化不同的类、类似的方法(不改变子类?),java,generics,composition,Java,Generics,Composition,不确定这是否可行,但我有一个例子,其中两个接口具有相同的方法。这些是给定的接口,因此我无法更改它们 给定接口 interface SomeGivenService { boolean authenticate(String username, String password); Object someSpecialMethod(Object param); } interface AnotherGivenService { boolean authenticate(St

不确定这是否可行,但我有一个例子,其中两个接口具有相同的方法。这些是给定的接口,因此我无法更改它们

给定接口

interface SomeGivenService {
    boolean authenticate(String username, String password);
    Object someSpecialMethod(Object param);
}

interface AnotherGivenService {
    boolean authenticate(String username, String password);
    String aGreatMethod();
    String sayHello();
}
为了使用这个服务,我创建了一个类,并进行了一些处理,以防这个服务抛出错误

class SomeGivenServiceConsumer {

    SomeGivenService a;

    public SomeGivenServiceConsumer(SomeGivenService a) {
        this.a = a;
    }

    public authenticate(MyUserPassBean bean) {
        try {
            a.authenticate(bean.username, bean.password);
        } catch (Exception e) {
            throw new MyException();
        }
        ...
    }
}

class AnotherGivenServiceConsumer {

    AnotherGivenService a;

    public AnotherGivenServiceConsumer(AnotherGivenService a) {
        this.a = a;
    }

    public authenticate(MyUserPassBean bean) {
        try {
            a.authenticate(bean.username, bean.password);
        } catch (Exception e) {
            throw new MyException();
        }
        ...
    }
}
在我的消费者中是否可以避免这种代码重复?我可能会有很多这样的代码,并希望避免这种重复的代码。 我最初考虑将我的使用者更改为接收实现此身份验证的接口,但由于我无法更改给定的接口,因此不确定这是否可行

有可能有一个“有方法的通用接口”或使用某种设计模式吗?有什么想法吗? 我想说的是:

class AnotherGivenServiceConsumer {

    AnotherGivenService a;
    GivenServiceAuthenticable b;

    public AnotherGivenServiceConsumer(AnotherGivenService a, 
                                       GivenServiceAuthenticable b) {
        this.a = a;
        this.b = b;
    }

    public authenticate(MyUserPassBean bean) throws MyException {
        return b.authenticate(bean.username, bean.password);
    }
}

interface GivenServiceAuthenticable<T> {
    boolean authenticate(T givenService, MyUserPassBean bean);
}

class GivenServiceAuthenticableImpl<T> implements GivenServiceAuthenticable<T> {
    boolean authenticate(T givenService, MyUserPassBean bean) {
        try {
            //this won't compile as it's a generic class..
            t.authenticate(bean.username, bean.password); 
        } catch (Exception e) {
            throw new MyException();
        }
        ...
    }
}
class AnotherGivenService Consumer{
另一项服务a;
givenservice可认证b;
另一个公共服务消费者(另一个公共服务a,
GivenService(可认证b){
这个a=a;
这个.b=b;
}
公共身份验证(MyUserPassBean bean)抛出MyException{
返回b.authenticate(bean.username、bean.password);
}
}
接口GivenServiceAuthenticatable{
布尔认证(T givenService,MyUserPassBean);
}
类GivenServiceAuthenticatableImpl实现GivenServiceAuthenticatable{
布尔身份验证(T givenService、MyUserPassBean){
试一试{
//由于它是泛型类,因此无法编译。。
t、 验证(bean.username、bean.password);
}捕获(例外e){
抛出新的MyException();
}
...
}
}

另一个问题是,如果无法更改此对象以实现新对象,如何实例化此对象?

您需要做的是使用继承。然后处理超类中的错误,即

    class SomeGivenServiceConsumer {

        SomeGivenService a;
        AnotherGivenService b;

        public SomeGivenServiceConsumer(SomeGivenService a) {
            this.a = a;
            try{
             authenticate(MyUserPassBean);
            }catch (Exception e) {
            System.out.println("Thrown exception has been caught : "+e.getMessage());
            }
        }

        public authenticate(MyUserPassBean bean) throws MyException {
                //your implementation here
        }
    }    
    class AnotherGivenServiceConsumer extends SomeGivenServiceConsumer{

        public AnotherGivenServiceConsumer(AnotherGivenService b) {
            super(someGivenService);//construct superclass
            authenticate(MyUserPassBean);//call subclass authenticate method
        }

        @override
        public authenticate(MyUserPassBean bean) throws MyException {
                super.authenticate(MyUserPassBean);//call superclass method
                //your implementation here

        }
    }
然后构造子类:

public static void main(String[] args) {
    new AnotherGivenServiceConsumer(AnotherGivenService);
}
可以使用实现基类中的公共功能,同时将单个可变行委托给子类:

abstract class ConsumerBase {
    public void authenticate(MyUserPassBean bean) {
        try {
            authenticate(bean.username, bean.password);
        } catch (Exception e) {
            throw new MyException();
        }
        //...
    }

    protected abstract boolean authenticate(String username, String password);
}

class SomeGivenServiceConsumer extends ConsumerBase {

    SomeGivenService a;

    public SomeGivenServiceConsumer(SomeGivenService a) {
        this.a = a;
    }

    @Override
    protected boolean authenticate(String username, String password) {
        return a.authenticate(username, password);
    }
}

class AnotherGivenServiceConsumer extends ConsumerBase {

    AnotherGivenService a;

    public AnotherGivenServiceConsumer(AnotherGivenService a) {
        this.a = a;
    }

    @Override
    protected boolean authenticate(String username, String password) {
        return a.authenticate(username, password);
    }
}

您的
authenticate
方法缺少返回类型。您有很多这样的服务,还是只有很多使用者?实现给定接口的所有类是否具有完全相同的身份验证逻辑?如果是,您只需引入一个新的
接口
,该接口扩展了给定的接口,并让您的
使用者
使用
身份验证(用户、密码)
方法的单个定义来实现此接口。@shmosel,我将为每个“givenservice”提供一个使用者。。我预计会有10个这样的接口,并且可能会增加这个数量。@ck实现给定接口的类具有完全相同的身份验证逻辑,但是每个“给定接口”都有一些不同的方法,这些方法必须由每个使用者实现,所以我需要不同的使用者。不确定我是否正确,但通过
interface AuthInterface扩展GivenService,另一个GivenService
它将要求每个使用者实现来自其他使用者的方法。。所以这是行不通的。。这就是你的意思吗?你忘了从
ConsumerBase
扩展;此外,只有当
GivenService
另一个GivenService
实现具有不同的方式/逻辑来认证用户时,这才有意义。如果他们有完全相同的代码/逻辑来验证用户,这将是一种过度杀戮。哼哼,这在@shmosel.中是有意义的。。这就是我要找的!谢谢妈的,他们的逻辑几乎是一样的。。唯一改变的是每个
消费者
从特定对象调用
身份验证
。。因此,我认为实现这一目标的唯一方法是使用这个
抽象方法。。谢谢
AnotherGivenService Consumer
无法扩展
SomeGivenService Consumer
,因为它们除了身份验证之外还有不同的方法。。但是假设你指的是一个基本消费者,你的想法与shmosel提出的类似。。除了我更喜欢他的,因为我仍然不需要调用构造函数上的
authenticate
。。但是非常感谢你的帮助!