num2 = num2 - num1; return num1;
}}
public class RationalTester
{
public static void main (String[] args)
{
RationalNumber r1 = new RationalNumber (6, 8); RationalNumber r2 = new RationalNumber (1, 3); RationalNumber r3, r4, r5, r6, r7; System.out.println ("First rational number: "
+ r1);
System.out.println ("Second rational number: " + r2);
if (r1.equals(r2))
System.out.println ("r1 and r2 are equal."); else
System.out.println ("r1 and r2 are NOT equal."); r3 = r1.reciprocal();
System.out.println ("The reciprocal of r1 is: " + r3); r4 = r1.add(r2);
r5 = r1.subtract(r2);
r6 = r1.multiply(r2);
r7 = r1.divide(r2); System.out.println ("r1 + r2: " + r4); System.out.println ("r1 - r2: " + r5); System.out.println ("r1 * r2: " + r6); System.out.println ("r1 / r2: " + r7);
}
}
Отношение Агрегация
Агрегация представляет собой объект, который состоит из других объектов. Поэтому агрегация является отношением между классами has-a .
Машина имеет (has a) двигатель.
В программном обеспечении, часто бывает, что совокупность объектов содержит ссылки на другие объекты, как данные экземпляра. Совокупный объект определяется частично объектами, которые его создают. Это особый вид зависимости - агрегация, как правило, зависит от объектов, составляющих его.
Пример Агрегации в нотации UML
Наследование в Java
В Java, мы используем слово - расширяет extends для наследования
• public class CheckingAccount extends BankAccount {
• объекты нового класса получают все поля (состояния) и поведение (методы) родительского класса
•Конструкторы и статические методы/поля не наследуются
•По умолчанию, родит. класс для всех Object
Сила Java в том, что только один родительский класс (“единичное наследование”)
Еще один пример - реализация наследования
class BankAccount { private double myBalance;
public BankAccount() { myBalance = 0; }
public double getBalance() {return myBalance; }
}
class CheckingAccount extends BankAccount { private double myInterest;
public CheckingAccount(double interest) { this.myInterest = interest;
}
public double getInterest() {return myInterest; } public void applyInterest() { }
}
Ссылки и наследование
Ссылка на объект может ссылаться только на объект своего же класса, или на объект любого класса, связанного с ним наследованием.
Например, если класс BankAccount используется для создания класса под названием CheckingAccount, то ссылку на объект BankAccount можно использовать, чтобы ссылаться на объект CheckingAccount.
Ассоциация с дочерним объектом родительской ссылки считается расширяющим тип преобразованием (upcasting), и может быть выполнена с помощью простого присваивания.
Назначение родительскому объекту дочерней ссылки также является допустимым (downcast), но считается сужающим преобразованием и должно быть выполнено с использованием операции преобразования типов.
Расширяющее преобразование является наиболее полезным.
Тип объекта, на который ссылаются, а не тип ссылки, определяет, какой метод будет вызывается.
Предположим класс BankAccount имеет метод, называемый pay(), и класс CheckingAccount переопределяет его.
Теперь рассмотрим следующий вызов: account.pay();
Если account ссылается на объект BankAccount, он вызывает версию pay() для BankAccount; если он ссылается на объект CheckingAccount, то вызывается версия pay() для CheckingAccount.
Отношение “Has-a”
Отношение "Has-a” : когда один объект содержит другой, как поле
public class BankAccountManager {
private List<Account> accounts; // ...
}
Например объект BankAccountManager имеет или содержит ("has-a») List внутри себя, и таким образом использует список счетов клиентов в качестве поля класса.
Отношение “Is-a”
отношение является ("Is-a”) представляет реализацию множество возможностей;
реализуется через интерфейсы и наследование
public class CheckingAccount extends BankAccount {
// ...
}
Объект CheckingAccount является ("is-a" ) BankAccount
Таким образом, он может делать то, что BankAccount может делать он может быть заменен везде, где необходимо на BankAccount
Переменная ссылка типа BankAccount может ссылаться на объект CheckingAccount
Пример с банковскими счетами
CheckingAccount наследует методы BankAccount
CheckingAccount c = new CheckingAccount(0.10);
System.out.println(c.getBalance());
c.applyInterest();
Переменная BankAccount может ссылаться на объект CheckingAccount
BankAccount b2 = new CheckingAccount(0.06);
System.out.println(b2.getBalance());
Переменная Object может указывать на любой тип счета клиента BankAccount так и CheckingAccount
Object o = new BankAccount();
Object o2 = new CheckingAccount(0.09);
Код, который не компилируется
Переменная CheckingAccount не может ссылаться на BankAccount
(не каждый BankAccount "is-a" CheckingAccount)
CheckingAccount c = new BankAccount();
Мы не можем вызвать метод CheckingAccount для переменной типа BankAccount (может только использовать поведение BankAccount)
BankAccount b = new CheckingAccount(0.10);
b.applyInterest();
Мы не можем переносить поведение счета на переменную типа Object
Object o = new CheckingAccount(0.06);
System.out.println(o.getBalance());
o.applyInterest();
Принцип Наследование
Свойства системы, позволяющие описать новый класс на основе уже существующего с частично или полностью заимствующейся функциональностью. Класс, от которого производится наследование, называется базовым, родительским или суперклассом. Новый класс — потомком, наследником, дочерним или производным классом. Общие свойства и методы объектов можно вынести в класс-«родитель». Все «дети»- наследники автоматически получают их.
Пример: Домашние животные -схема наследования
Пример: класс Домашнее животное
public class Pet { private String name; private int age;
public Pet() { this("Unnamed");}
public Pet(String name) {name = "Unnamed";} public Pet(String name, int age) {
this.name = name; this.age = age;