2017-02-17 28 views
1

Код работает, но я хотел бы лучше понять тему и не знаю, как назвать проблему. Как возможно, что в методе абстрактного класса я могу вызвать метод интерфейса, если метод интерфейса пуст? Может ли кто-нибудь рассказать мне, как эта операция называется на Java? В моих классах uni, которые я посещаю, слайд называет проблему «Программирование через API», но я не могу найти что-либо, когда я это делаю.вызов метода интерфейса в методе абстрактного класса

У меня есть класс интерфейса, который имеет метод getBalance:

public interface BankAccount { 

int getBalance(); 
... 
} 

Тогда я вызывающий метод интерфейса в абстрактном методе класса:

public abstract class AbstractBankAccount implements BankAccount { 

private final bankAccountNo; 
private int accountBalance; 

abstractBankAccount(int bankAccountNo) { 
    this.bankAccountNo = bankAccountNo; 
} 

public void transferBalance(bankAccount account) { 

// so here is what I am struggling to understand: account.getBalance() is called, but getBalance() method in interface is empty, how does it work then? 

final int accountBal = account.getBalance(); 

    if (accountBal < 0) 
     throw new IllegalArgumentException("not enough money on the account"); 

    accountBalance += accountBal; 

    account.withdraw(accountBal); 
} 
} 

ответ

3

В абстрактном классе некоторые методы оставлены для конкретных наследников для реализации.

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

Вот пример:

abstract class Parent { 
    abstract String someMethod(); 

    public String getValue() { 
    return someMethod();//how could this work?! someMethod() has no body! 
    } 
} 

class Child extends Parent { 

    @Override 
    String someMethod() { //this won't compile unless I implement someMethod() 
    return "data"; 
    } 
} 

Хотя SomeMethod() абстрактна в Родитель, вы не можете на самом деле создать экземпляр Родитель (потому что он является абстрактным). Вы должны расширить его, что требует от вас реализации someMethod().

0

Ответ заключается в том, что при его запуске параметр account будет экземпляром конкретного класса, который реализует bankAccount.getBalance(). Это как абстракция работает

+0

Спасибо, что очищает вещи для меня. Это такое действие в Java, называемое «программирование по интерфейсу»? – FervidWhirl

0

В моих однотонный классах, которые я посещаю, имена слайда проблема, как «Программирование через API», но я не могу найти что-нибудь, когда я Google его.

и

Как это возможно, что в методе абстрактного класса я могу вызвать метод интерфейса, если метод интерфейса пуст?

В методах конкретного класса вы можете встретить точно такую ​​же ситуацию.
Здесь интерфейс определяет контракт: методы для реализации, но все они абстрактны в интерфейсе.
Для программирования по интерфейсу код, управляющий концепцией, помещенной в интерфейс (здесь BankAccount), не должен напрямую ссылаться на конкретный класс интерфейса, но сам интерфейс, если мы хотим иметь возможность переключиться на другой класс реализации интерфейса ,

Именно поэтому public void transferBalance(BankAccount account) определяется как параметр BankAccount.

Конечно, в определенный момент должен быть выбран и создан конкретный класс, но это единственный раз, когда он должен быть указан.

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

// I instantiate concrete classes but I refer interface as declared type. 
BankAccount bankAcountDebitor = new ConcreteBankAccount(); 
BankAccount bankAcountCreditor = new ConcreteBankAccount(); 

// I invoke a method that takes as argument a type derived from the interface type 
bankAcountDebitor.transferBalance(bankAcountCreditor); 

Таким образом, даже если в день мы переходим к другому конкретному BankAccount представлению:

bankAcountDebitor.transferBalance(bankAcountCreditor); 

будет компилироваться, как метод принимает в качестве параметра тип интерфейса.

Таким образом, вы могли бы написать, что:

BankAccount bankAcountDebitor = new ConcreteUniversalBankAccount(); 
BankAccount bankAcountCreditor = new ConcreteUniversalBankAccount(); 

bankAcountDebitor.transferBalance(bankAcountCreditor); 
+0

Благодарим вас за ответ. Я хорошо это понимаю? Параметр «account» в моем методе transferBalance() всегда относится к конкретной реализации класса интерфейса (например, ConcreteBankAccount)? Является ли это такая операция, называемая «программирование по интерфейсу» на Java? – FervidWhirl

+0

Добро пожаловать :) 1) yes переданный параметр всегда ссылается на конкретную реализацию класса интерфейса. Это ограничение компиляции, поскольку для параметра, которому требуется компилятор, нужен конкретный экземпляр, но он также должен выводиться из объявленного типа интерфейса. 2) В вашем фактическом коде 'public void transferBalance (BankAccount account)' относится к программированию по интерфейсу. Мы раскрываем интерфейс 'BankAccount' как объявленный тип. Таким образом, мы можем передать любую реализацию параметра «BankAccount» в качестве параметра, и переданный объект будет обрабатываться только в том случае, если интерфейс «BankAccount» предоставляет его. – davidxxx

+0

спасибо за хорошее объяснение, это помогло мне :) – FervidWhirl