1. Bank (наследување, полиморфизам и интерфејси)
Дадени се следниве пет класи:
-
Bank -
Account -
NonInterestCheckingAccount -
InterestCheckingAccount -
PlatinumCheckingAccount
како и интефејс наречен InterestBearingAccount кои се однесуваат на следниот начин:
-
Во
Bankчува листа од сите видови сметки, вклучувајќи сметки за штедење и за трошење, некои од нив подложни на камата, а некои не. ВоBankпостои методtotalAssetsкој ја враќа сумата на состојбата на сите сметки. Исто така содржи методaddInterestкој го повикува методотaddInterestна сите сметки кои се подложни на камата. -
Accountе апстрактна класа. Во секој сметка се чуваат името на сопственикот на сметката, бројот на сметката (секвенцијален број доделен автоматски), моменталната состојба. Во класата се имплементираат конструктор за иницијализација на податочните членови, методи за пристап до моменталната состојба, како и за додавање и одземање од моменталната состојба. -
InterestBearingAccountинтерфејсот декларрира единствен методaddInterest(без параметри и не враќа ништо -void) кој ја зголемува состојбата со соодветната камата за овој вид на сметка. -
InterestCheckingAccountе сметкаAccountкоја е исто такаInterestBearingAccount. ПовикувањеaddInterestја зголемува состојбата за 3%. -
PlatinumCheckingAccountеInterestCheckingAccount. ПовикувањеaddInterestја зголемува состојбата двојно од каматата заInterestCheckingAccount(колку и да е таа). -
NonInterestCheckingAccountе сметкаAccountно не еInterestBearingAccount. Нема дополнителни функционалности надвор од основните од класатаAccount.
За оваа задача, потребно е да се имплментира функционалност дадена во претходниот текст:
-
Пет од шест класи од споменатите формираат хиерархија. За овие класи да се нацрта оваа хиерархија.
-
Да се имплементира
Account. -
Да се имплементира
NonInterestCheckingAccount. -
Да се напише
InterestBearingAccountинтерфејсот. -
Да се имплементира
Bank. -
Да се имплементира
InterestCheckingAccount. -
Да се имплементира
PlatinumCheckingAccount.
Account.java)package mk.ukim.finki.np.av4.bank;
public abstract class Account {
private String holderName;
private int number;
private double currentAmount;
public Account(String holderName, int number, double currentAmount) {
this.holderName = holderName;
this.number = number;
this.currentAmount = currentAmount;
}
public double getCurrentAmount() {
return currentAmount;
}
public void addAmount(double amount) {
currentAmount += amount;
}
public void withdrawAmount(double amount) {
currentAmount -= amount;
}
}
NonInterestCheckingAccount.java)package mk.ukim.finki.np.av4.bank;
public class NonInterestCheckingAccount extends Account {
public NonInterestCheckingAccount(String holderName, int number, double currentAmount) {
super(holderName, number, currentAmount);
}
}
InterestBearingAccount.java)package mk.ukim.finki.np.av4.bank;
public interface InterestBearingAccount {
void addInterest();
}
Bank.java)package mk.ukim.finki.np.av4.bank;
import java.util.Arrays;
public class Bank {
private Account[] accounts;
private int totalAccounts;
private int max;
public Bank(int max) {
this.totalAccounts = 0;
this.max = max;
accounts = new Account[max];
}
public void addAccount(Account account) {
if (totalAccounts == accounts.length) {
accounts = Arrays.copyOf(accounts, max * 2);
}
accounts[totalAccounts++] = account;
}
public double totalAssets() {
double sum = 0;
for (Account account : accounts) {
sum += account.getCurrentAmount();
}
return sum;
}
public void addInterest() {
for (Account account : accounts) {
if (account instanceof InterestBearingAccount) {
InterestBearingAccount iba = (InterestBearingAccount) account;
iba.addInterest();
}
}
}
}
InterestCheckingAccount.java)package mk.ukim.finki.np.av4.bank;
public class InterestCheckingAccount
extends Account implements InterestBearingAccount {
public static final double INTEREST_RATE = .03; // 3%
public InterestCheckingAccount(String holderName, int number, double currentAmount) {
super(holderName, number, currentAmount);
}
@Override
public void addInterest() {
addAmount(getCurrentAmount() * INTEREST_RATE);
}
}
PlatinumCheckingAccount.java)package mk.ukim.finki.np.av4.bank;
public class PlatinumCheckingAccount extends Account implements
InterestBearingAccount {
public PlatinumCheckingAccount(String holderName, int number, double currentAmount) {
super(holderName, number, currentAmount);
}
@Override
public void addInterest() {
addAmount(getCurrentAmount() * InterestCheckingAccount.INTEREST_RATE * 2);
}
}
2. Наследување (рефакторирање)
Следниот код е дизајниран од J. Hacker за видео игра.
Постои класа Alien која репрезентира вонземјанин и класа AlienPack која репрезентира група вонземјани и колку штета може да нанесат:
Alian.javapackage mk.ukim.finki.np.av4;
public class Alien {
public static final int SNAKE_ALIEN = 0;
public static final int OGRE_ALIEN = 1;
public static final int MARSHMALLOW_MAN_ALIEN = 2;
public int type; // Stores one of the three above types
public int health; // 0=dead, 100=full strength
public String name;
public Alien(int type, int health, String name) {
this.type = type;
this.health = health;
this.name = name;
}
}
AlianPack.javapackage mk.ukim.finki.np.av4;
public class AlienPack {
private Alien[] aliens;
public AlienPack(int numAliens) {
aliens = new Alien[numAliens];
}
public void addAlien(Alien newAlien, int index) {
aliens[index] = newAlien;
}
public Alien[] getAliens() {
return aliens;
}
public int calculateDamage() {
int damage = 0;
for (int i = 0; i < aliens.length; i++) {
if (aliens[i].type == Alien.SNAKE_ALIEN) {
damage += 10;// Snake does 10 damage
} else if (aliens[i].type == Alien.OGRE_ALIEN) {
damage += 6;// Ogre does 6 damage
} else if (aliens[i].type == Alien.MARSHMALLOW_MAN_ALIEN) {
damage += 1;
// Marshmallow Man does 1 damage
}
}
return damage;
}
}
Кодот не е многу објектно ориентиран и не подржува криење на информациите во класата Alien.
Да се пренапише, така што ќе се искористи наследување за да се репрезентираат различни типови вонземјани, наместо да се користи параметарот type.
Исто така пренапишете jа класата Alien така што ќе ги крие инстанцните променливи и додадете метод getDamage коj за секоја од изведените класа ќе jа врак̀а штетата која jа предизвикува.
На крај пренапишете го методот calculateDamage да го користи getDamage и напишете main метод да ја тестирате класата.
3. Читање од стандарден влез (SI)
3.1. Калкулатор
Да се напише програма едноставен калкулатор.
Калкулаторот чува еден број од тип double со име резултат и неговата почетна вредност е 0.0.
Во циклус му се дозволува на корисникот да додаде, одземе, помножи или подели со втор број.
Резултатот од овие операции е новата вредност на резултатот.
Пресметката завршува кога корисникот ќе внесе R за result (како мала или голема буква).
Корисникот може да направи уште една пресметка од почеток или да ја заврши програмата (Y/N).
Ако корисникот внесе различен знак за оператор од +, -, * или /, тогаш се фрла исклучок UnknownOperatorException и се чека повторно на внес.
Calculator is on.
result = 0.0
+5
result + 5.0 = 5.0
new result = 5.0
* 2.2
result * 2.2 = 11.0
updated result = 11.0
% 10
% is an unknown operation.
Reenter, your last line:
* 0.1
result * 0.1 = 1.1
updated result = 1.1
r
Final result = 1.1
Again? (y/n)
yes
result = 0.0
+10
result + 10.0 = 10.0
new result = 10.0
/2
result / 2.0 = 5.0
updated result = 5.0
r
Final result = 5.0
Again? (y/n)
N
End of Program
package mk.ukim.finki.np.av4;
public class Calculator {
private double result;
private static final char PLUS = '+';
private static final char MINUS = '-';
private static final char MULTIPLY = '*';
private static final char DIVIDE = '/';
public Calculator() {
result = 0;
}
public String init() {
return String.format("result = %f", result);
}
public double getResult() {
return result;
}
public String execute(char operator, double value)
throws UnknownOperatorException {
if (operator == PLUS) {
result += value;
} else if (operator == MINUS) {
result -= value;
} else if (operator == MULTIPLY) {
result *= value;
} else if (operator == DIVIDE) {
result /= value;
} else {
throw new UnknownOperatorException(operator);
}
return String.format("result %c %f = %f", operator, value, result);
}
class UnknownOperatorException extends Exception {
public UnknownOperatorException(char operator) {
super(String.format("%c is unknown operation", operator));
}
}
@Override
public String toString() {
return String.format("updated result = %f", result);
}
}
package mk.ukim.finki.np.av4;
import java.util.Scanner;
public class CalculatorTest {
static final char RESULT = 'r';
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (true) {
Calculator calculator = new Calculator();
System.out.println(calculator.init());
while (true) {
String line = scanner.nextLine();
char choice = getCharLower(line);
if (choice == RESULT) {
System.out.println(String.format("final result = %f", calculator.getResult()));
break;
}
String[] parts = line.split("\\s+");
char operator = parts[0].charAt(0);
double value = Double.parseDouble(parts[1]);
try {
String result = calculator.execute(operator, value);
System.out.println(result);
System.out.println(calculator);
} catch (Calculator.UnknownOperatorException e) {
System.out.println(e.getMessage());
}
}
System.out.println("(Y/N)");
String line = scanner.nextLine();
char choice = getCharLower(line);
if (choice == 'n') {
break;
}
}
}
static char getCharLower(String line) {
if (line.trim().length() > 0) {
return Character.toLowerCase(line.charAt(0));
}
return '?';
}
}