ООП и UML Продолжение истории классов и объектов Инкапсуляция – важный принцип ООП Однако, на инкапсуляции история классов и объектов не заканчивается Наследование – создание новых классов с использованием уже описанных классов Наследование • Уточнение: класс-потомок добавляет некоторые существенные черты к родительскому состоянию, добавляет особое поведение • Перекрытие: класс-потомок изменяет некоторые аспекты поведения класса-родителя, перекрывая методы последнего Как не нужно делать Множественное наследование позволяет нескольким объектам выступать в роли базовых и поддерживается во многих языках. Характеристики нескольких различных классов объектов могут комбинироваться, создавая новый объект. Например, пусть мы имеем класс объектов CAR, инкапсулирующий информацию об автомобиле, и класс PERSON, инкапсулирующий информацию о человеке. Мы можем использовать их для определения нового класса CAR-OWNER, комбинирующего атрибуты CAR и PERSON. Наследование в Java • • • • • • • Наследование с помощью ключевого слова extends Только единичное наследование Только public наследование По умолчанию – наследование от java.lang.Object К классу-родителю можно обратиться с помощью super Ключевое слово this – ссылка на самого себя Наследование можно запретить, используя final this public class Test { int b = this.a; int a = 5; { sout(a+" "+b); } } Полиморфизм – способность объектов одного типа вести себя подобно объектам другого типа Перекрытие методов • Для перекрытия методов достаточно в классе-потомке объявить метод с той же сигнатурой, что и в классе-родителе • Перекрытие методов можно запретить, пометив метод ключевым словом final • static методы нельзя перекрывать • Начиная с Java 5, перекрывающие методы рекомендуется помечать аннотацией @Override Полиморфизм. Поля public class A { public int a = 1; public int getA() { return a; } } public class B extends A { public int a = 2; } public class C{ public static void main(String[] args) { B b = new B(); System.out.println(b.a); A a = b; System.out.println(a.a); System.out.println(b.getA()); } } Результат: 2 1 1 Статические поля class A{ static int a; } class B extends A{ } B.a=2; A.a=1; sout(B.a); Результат: 1 Методы class A{ public int get(){ return 1; } } B b = new B(); sout(b.get()); A a = b; sout(a.get()); class B extends A{ public int get(){ return 2; } } Результат: 2 2 Абстрактные классы и методы • Абстрактные методы не имеют тела • Абстрактный метод помечается ключевым словом abstract • Если в классе есть абстрактный метод, то и класс необходимо пометить ключевым словом abstract • Класс может быть абстрактным и в том случае, если у него нет абстрактных методов. • Абстрактный класс не может быть final Абстрактные классы public abstract class BaseEntity { private BigInteger id; public BigInteger getId() { return id; } public class User extends BaseEntity { private String name; private String password; … } public void setId(BigInteger id) { this.id = id; } } Множественное наследование • Для классов можно использовать только единичное наследование • Вместо множественного наследования можно использовать интерфейсы Интерфейсы в Java • Интерфейсы содержат только объявления методов и (или) констант • Реализация интерфейса – с помощью ключевого слова implements • Что будет, если реализовать не все методы интерфейса? Интерфейсы public interface DAO { public void save(BaseEntity entity); public BaseEntity findById(BigInteger id); } class SimpleDAO implements DAO{ @Override public void save(BaseEntity entity){ //body } @Override public BaseEntity findById(BigInteger id) { //body return null; } } Наследование и полиморфизм public class A { public int getY() { sout("(A)return y="+y); return y; } private int y = getY(); { sout("initialization A"); } A(){sout("Cons A"); } public class B extends A { public int getY() { sout("(B)return y="+y); return y; } private int y = getY(); { sout("initialization B"); } B(){sout("Cons B"); } static { sout("static B"); } static { sout("static A"); } } } Наследование и полиморфизм public class Main { public static void main(String[] args) { B b = new B(); } } //Что будет напечатано? static A static B (B)return y=0 initial A Cons A (B)return y=0 initial B Cons B