Как написать настоящий метод по умолчанию, чтобы избежать дублирования кода - PullRequest
0 голосов
/ 04 июня 2018

Я хочу написать два класса, реализующих интерфейс с методом по умолчанию с параметром - именем функции, и использовать его в обоих классах, но не знаю, как поместить имя метода в качестве параметра.Необходимо избегать дублирования.

interface C {
        default public StatusEntry getServiceStatus(){????}
}

class A implements C { 

    private StatucBType getSatusA(){...} 

    @Override
    public StatusEntry getServiceStatus() throws Exception {
        StatusEntry result = new StatusEntry();
        ServiceStatus status;
        try {
            status = **getSatusA()**/*need make as a parametr*/.getStatus();
        } catch (Exception e) {
        }
        result.Status(status);
        return result;
    }
}

class B implements C {    
    private StatucBType getSatusB(){...}

    @Override
    public StatusEntry getServiceStatus() throws Exception {
        StatusEntry result = new StatusEntry();
        ServiceStatus status;
        try {
            status = **getSatusB()**/*need make as a parametr*/.getStatus();
        } catch (Exception e) {
        }
        result.Status(status);
        return result;
    }
}

Ответы [ 2 ]

0 голосов
/ 04 июня 2018

Если вы добавляете параметр к методу getServiceStatus в своем интерфейсе, конкретные реализации также должны добавить этот параметр, и - что более важно - вызывающие этого метода должны знать, какой аргумент предоставить.

Поэтому, во-первых, не добавляйте параметр в этот интерфейс (по крайней мере, в этом небольшом сценарии это не нужно)!

Чтобы избежать дублирования кода, вы можете добавить промежуточный абстрактный класс, содержащий код:

abstract class Z {

    final StatusEntry getServiceStatus(Supplier<StatucBType> statusProvider) throws Exception {
        StatusEntry result = new StatusEntry();
        ServiceStatus status;
        try {
            status = statusProvider.get().getStatus();
        } catch (Exception e) {
        }
        result.Status(status);
        return result;
    }

}

Затем используйте его следующим образом:

class A implements C extends Z { 

    private StatucBType getSatusA() {...} 

    @Override
    public StatusEntry getServiceStatus() throws Exception {
        return getServiceStatus(this::getStatusA);
    }

}
0 голосов
/ 04 июня 2018

Возможно, вы ищете шаблон метода шаблона .

Ваш интерфейс должен иметь только метод getStatus,

StatucBType getStatus();

и getServiceStatusметод будет default и реализован так:

default StatusEntry getServiceStatus() throws Exception {
    StatusEntry result = new StatusEntry();
    ServiceStatus status;
    try {
        status = getStatus().getStatus();
    } catch (Exception e) {
    }
    result.Status(status);
    return result;
}

Теперь вам нужно реализовать getStatus в A и B:

// in A
public StatucBType getStatus { /*put the implementation of getStatusA here*/}
// in B
public StatucBType getStatus { /*put the implementation of getStatusB here*/}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...