【问题标题】:How to implement the interaction among abstract and inherited classes?如何实现抽象类和继承类之间的交互?
【发布时间】:2020-07-19 10:02:36
【问题描述】:

我必须使用@Override 方法来实现抽象类和继承类之间的交互。问题是我不知道该怎么做,这是我的任务:

我用 3 个方法(pay(int amount)transfer(Account account, int amount)addMoney(int amount))创建了一个抽象类 Account。付款必须看起来像普通的扣除。我重写了方法。每个人都必须有一个平衡。我不能SavingsAccount 付款,只能转账和添加。它也不能降为负数。 CreditAccount 不能有一个正余额 - 如果我支付它,它会下降到负数,返回 0,我需要添加它。 CheckingAccount 实现了所有这些方法,但不能降为负数。

我必须创建 3 个帐户类型变量并为它们提供 3 种不同的帐户类型。代码来了:

public abstract class Account {
    protected int amount;
    protected int balance;

    public Account(int amount, int balance) {
        this.amount = amount;
        this.balance = balance;
    }

    void pay(int amount) {
    }

    void transfer(Account account, int amount) {
    }

    void addMoney(int amount) {
    }
}

public class CheckingAccount extends Account {
    public CheckingAccount(int amount, int balance) {
        super(amount, balance);
    }

    @Override
    void pay(int amount) {
        super.pay(amount);
    }

    @Override
    void transfer(Account account, int amount) {
        super.transfer(account, amount);
    }

    @Override
    void addMoney(int amount) {
        super.addMoney(amount);
    }
}
public class CreditAccount extends Account {
    public CreditAccount(int amount, int balance) {
        super(amount, balance);
    }

    @Override
    void pay(int amount) {
        super.pay(amount);
    }

    @Override
    void transfer(Account account, int amount) {
        super.transfer(account, amount);
    }

    @Override
    void addMoney(int amount) {
        super.addMoney(amount);
    }
}

public class SavingsAccount extends Account {
    public SavingsAccount(int amount, int balance) {
        super(amount, balance);
    }

    @Override
    void transfer(Account account, int amount) {
        balance -= amount;
    }

    @Override
    void addMoney(int amount) {
        super.addMoney(amount);
    }
}

【问题讨论】:

  • 我还是不明白问题
  • 这是一个糟糕的类设计(“interface bloat”并违反了Liskov substitution principle)。由于您的特定帐户类型未实现Account 强加的合同,因此它们不应扩展该基类。有几种方法可以解决这个问题——可能最简单的方法是拥有单独的多个“特征”接口,并让每个类实现它支持的那些特征。
  • 同意conrad,最好分成三个接口。可转让、可支付、可添加。
  • @KonradRudolph 和 AbhirojPanwar 你们只是想修复他的结构吗?或者你明白这个问题吗?如果您这样做,请帮助我们理解,我可以看到可能缺少类结构,但问题从未得到解决,或者是这样吗?
  • amount 成员是做什么用的?

标签: java methods overriding abstract


【解决方案1】:

似乎基类必须实现一些通用功能,并且它没有任何抽象方法。所以它被标记为抽象以避免实例化。

此外,似乎没有在帐户级别定义验证(金额是否应为正数)。

public abstract class Account {
    protected int amount;
    protected int balance;

    public Account(int amount, int balance) {
        this.amount = amount;
        this.balance = balance;
    }

    void pay(int amount) {
        if (amount > 0)
            this.balance -= amount;
        else
            throw new IllegalArgumentException("Amount must be positive");
    }

    void transfer(Account recipient, int amount) {
        recipient.addMoney(amount);
        this.balance -= amount;
    }

    void addMoney(int amount) {
        this.balance += amount;
    }
}

然后CheckingAccount 的实现需要重写方法来验证结果余额:

public class CheckingAccount extends Account {
    public CheckingAccount(int amount, int balance) {
        super(amount, balance);
    }

    @Override
    void pay(int amount) {
        if (this.balance >= amount) {
            super.pay(amount);
        } else {
            throw new IllegalArgumentException("Insufficient funds");
        }
    }

    @Override
    void transfer(Account recipient, int amount) {
        if (this.balance - amount >= 0) {
            super.transfer(recipient, amount);
        } else {
            throw new IllegalArgumentException("Insufficient funds for transfer from CheckingAccount");
        }
    }

    @Override
    void addMoney(int amount) {
        if (this.balance + amount >= 0) {
            super.addMoney(amount);
        } else {
            throw new IllegalArgumentException("Balance may not be negative for CheckingAccount");
        }
    }
}

对于SavingsAccount pay 方法必须被重写以引发异常。 可能值得覆盖transferaddMoney 以验证类似于CheckingAccount 的余额。

public class SavingsAccount extends Account {
    public SavingsAccount(int amount, int balance) {
        super(amount, balance);
    }

    @Override
    void pay(int amount) {
        throw new RuntimeException("This method is not supported for Savings account");
    }
}

最后一个CreditAccount 你可能想检查余额是否不是正数,同时使用pay 的默认实现(虽然信用账户也应该有信用额度):

public class CreditAccount extends Account {
    public CreditAccount(int amount, int balance) {
        super(amount, balance);
    }

    @Override
    void transfer(Account account, int amount) {
        if (this.balance - amount <= 0) {
            super.transfer(account, amount);
        } else {
            throw new IllegalArgumentException("Balance may not be positive for CreditAccount");
        }
    }

    @Override
    void addMoney(int amount) {
        if (this.balance + amount <= 0) {
            super.addMoney(amount);
        } else {
            throw new IllegalArgumentException("Balance may not be positive for CreditAccount");
        }
    }
}

此示例仅是为了遵守上述实施要求。

因此,它不满足类似于初始类设计的 cmets 中提到的 Liskov 原则。

此外,为简洁起见,示例中使用了运行时异常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-16
    • 1970-01-01
    • 1970-01-01
    • 2011-11-03
    相关资源
    最近更新 更多