Java, каф.ОСУ, АВТФ1 Наследование Наследование позволяет использовать существующий класс для определения новых классов, т.е. способствует многократному использованию программного обеспечения. Полиморфизм это такой способ применения наследования, при котором различные виды объектов используют различные определения (различные действия) одного и того же имени метода. Каков отец, такой и сын Разработал к.т.н. Фофанов О.Б.
Java, каф.ОСУ, АВТФ2 Наследование Наследование позволяет определить очень общий класс, а затем (позже) определять более специализированные подклассы простым добавлением новых деталей в созданное более общее определение класса. При этом экономится труд программиста, поскольку более специализированный подкласс наследует все свойства общего класса, и программисту, остается запрограммировать только новые свойства подкласса
Java, каф.ОСУ, АВТФ3 Наследование EXAMPLE. Определение базового (супер) класса public class Person { private String name; public Person() { name = "Пока без имени."; } public Person(String initialName) { name = initialName; }
Java, каф.ОСУ, АВТФ4 Наследование public void setName(String newName){ name = newName; } public String getName( ){ return name; } public void writeOutput( ) { System.out.println("Имя: " + name); }
Java, каф.ОСУ, АВТФ5 Наследование public boolean sameName(Person otherPerson){ return (this.name.equalsIgnoreCase(otherPerson. name)); } } //p1.name.equalsIgnoreCase(p2.name)
Java, каф.ОСУ, АВТФ6 Производные классы Производный класс (derived class) это класс, определяемый путем добавления переменных реализации и методов в некоторый уже существующий класс. Существующий класс, на базе которого строится производный, называется базовым классом (base class). Производный класс имеет все доступные переменные реализации и доступные методы базового класса плюс все дополнительные переменные реализации и методы, которые программист считает нужным добавить
Java, каф.ОСУ, АВТФ7 Производные классы Синтаксис public class Имя_Производного_Класса extends Имя_Базового_Класса { }
Java, каф.ОСУ, АВТФ8 Производные классы // Определение производного класса public class Student extends Person { private int studentNumber; public Student ( ){ super () ; studentNumber = 0; // 0 - означает отсутствие номера. }
Java, каф.ОСУ, АВТФ9 Производные классы public Student(String initialName, int initialStudentNumber) { super(initialName); studentNumber = initialStudentNumber; } public void reset (String newName, int newStudentNumber);{ setName (newName) ; studentNumber = newStudentNumber; }
Java, каф.ОСУ, АВТФ10 Производные классы public int getstudentNumber() { return studentNumber; } public void setstudentNumber(int newStudentNumber) { studentNumber = newStudentNumber; }
Java, каф.ОСУ, АВТФ11 Производные классы public void writeOutput() {// переопределение метода баз.класса System.out. println( "Имя: " + getName( ); System.out.println("Номер студента : " + studentNumber); } public boolean equals(Student otherStudent) { return (this. sameName (otherStudent) && (this. studentNumber == otherStudent. studentNumber) ) } }
Java, каф.ОСУ, АВТФ12 Производные классы …. Student s1 = new Student (); Student s2 = new Student(Mel Gibson, 55551); s1.setName (Garry Potter); s1.setStudentNumber (20001); if s1.equals (s2) System.out.println ( Один и тот же);…
Java, каф.ОСУ, АВТФ13 Производные классы Переопределение методов Если в производный класс включить определение метода с таким же именем и с таким же количеством параметров таких же типов, как в определении метода в базовом классе, то для производного класса это новое определение метода заменяет старое. (writeOutput)
Java, каф.ОСУ, АВТФ14 Производные классы В таких случаях тип значения, возвращаемого переопределяемым методом, должен совпадать с типом значения, возвращаемого методом в базовом классе. Т.е., при переопределении метода нельзя менять тип значения, возвращаемого этим методом.
Java, каф.ОСУ, АВТФ15 Производные классы Если метод в производном классе имеет другое количество параметров или параметры другого типа по сравнению с методом в базовом классе, то производный класс будет иметь оба метода – перегрузка имени метода Класс Student: | public String getName (String title){ return (title + getName()); } // 2 метода getName
Java, каф.ОСУ, АВТФ16 Производные классы Если данное определение метода не должно заменяться новым определением в производном классе, достаточно добавить в заголовок метода модификатор final Если метод объявляется с использованием модификатора final, компилятор тем самым получает больше информации о характере его использования, что позволяет ему сгенерировать для данного метода более эффективный код. С помощью модификатора final можно объявить целый класс, и тогда его нельзя использовать в качестве базового класса для создания из него других (производных) классов.
Java, каф.ОСУ, АВТФ17 Производные классы К переменной реализации (или методу), которая закрыта в базовом классе, нельзя получить доступ по имени в определении метода любого другого класса, даже в определении метода производного класса. public void reset(String newName, int newStudentNumber) { name = newName;//НЕДОПУСТИМО //setName (newName) ;….
Java, каф.ОСУ, АВТФ18 Производные классы Когда мы применяем фразу super это означает обращение к конструктору базового класса: super (initialName); // запрещено использовать // Person (initialName) Если обращение к конструктору базового класса отсутствует, Java вставит обращение к конструктору базового класса, действующему по умолчанию,т.е. Java автоматически вставит вызов super ()
Java, каф.ОСУ, АВТФ19 Производные классы Определяя конструктор производного класса, в качестве имени конструктора класса можно использовать зарезервированное слово super. Обращение к super должно быть первым действием, предпринимаемым конструктором.
Java, каф.ОСУ, АВТФ20 Производные классы public Student(String initialName, int initialStudentNumber) { super(initialName); studentNumber = initialStudentNumber; } использование this обеспечивает вызов конструктора того же класса, а не конструктора базового класса.
Java, каф.ОСУ, АВТФ21 Производные классы добавить в класс student public Student(String initialName) { this(initialName, 0); } //вызов конструктора // public Student(String initialName, int initialStudentNumber)
Java, каф.ОСУ, АВТФ22 Производные классы Слово super можно также использовать для вызова метода базового класса, который переопределяется в производном классе //альтернативное определение метода //writeOutput для класса Student public void writeOutput () { super.writeOutput() ; System.out.println("Номер студента: " + studentNumber);}
Java, каф.ОСУ, АВТФ23 Многоуровневые производные классы Из любого производного класса можно создать производные классы. public class Undergraduate extends Student { private int level;// 1 для студента // первого курса, //2 для студента-второкурсника и т.д. public Undergraduate() { super(); level = 1; }
Java, каф.ОСУ, АВТФ24 Многоуровневые производные классы public Undergraduate (String initialName, int initialStudentNumber, int initialLevel){ super(initialName, initialStudentNumber); level = initialLevel; } public int getLevel(){ return level; } public void setLevel (int newLevel){ level = newLevel; }
Java, каф.ОСУ, АВТФ25 Многоуровневые производные классы public void reset(String newName, int newStudentNumber, int newLevel){ reset(newName, newStudentNumber); level = newLevel; } public void writeOutput() { super.writeOutput() ; System.out.println("Уровень студента: " + level) }….
Java, каф.ОСУ, АВТФ26 Многоуровневые производные классы При вызове конструктора класса Undergraduate (с помощью оператора new) сначала вызывается конструктор класса Person, затем конструктор класса Student, а затем выполняются все операторы, следующие за вызовом super в конструкторе класса Undergraduate.
Java, каф.ОСУ, АВТФ27 Конструкторы при наследовании При создании экземпляра класса вызванный конструктор выполняется следующим образом: 1.если первой строкой идет обращение к конструктору родительского класса (явное или добавленное компилятором по умолчанию), то этот конструктор исполняется; 2.в случае успешного исполнения вызываются все инициализаторы полей объекта в том порядке, в каком они объявлены в теле класса;
Java, каф.ОСУ, АВТФ28 Конструкторы при наследовании 3.если первой строкой идет обращение к другому конструктору этого же класса, то он вызывается. Повторное выполнение инициализаторов не производится.
Java, каф.ОСУ, АВТФ29 Конструкторы при наследовании Второй пункт имеет ряд важных следствий. Во-первых, из него следует, что в инициализаторах нельзя использовать переменные класса, если их объявление записано позже Во-вторых, теперь можно сформулировать наиболее гибкий подход к инициализации final- полей. Главное требование – чтобы такие поля были проинициализированы ровно один раз. Это можно обеспечить в следующих случаях:
Java, каф.ОСУ, АВТФ30 Конструкторы при наследовании если инициализировать поле при объявлении; если инициализировать поле только один раз в инициализаторе объекта (он должен быть записан после объявления поля); если инициализировать поле только один раз в каждом конструкторе, в первой строке которого стоит явное или неявное обращение к конструктору родителя.
Java, каф.ОСУ, АВТФ31 Многоуровневые производные классы Объект производного класса имеет несколько типов Объект производного класса имеет тип этого производного класса, а также тип базового класса, и более того, тип каждого из классов- предков В Java каждый класс является потомком встроенного класса Object. Поэтому каждый объект любого класса имеет тип Object, а также тип своего класса (а также тип любого другого класса-предка).
Java, каф.ОСУ, АВТФ32 Многоуровневые производные классы Поскольку объект производного класса имеет тип всех своих классов- предков (также как свой "собственный" тип), то объект этого класса можно присвоить переменной любого типа предка, но не наоборот: Person p1, р2; p1 = new Student (); р2 = new Undergraduate (); Student s = new Person(); //НЕВЕРНО!
Java, каф.ОСУ, АВТФ33 Многоуровневые производные классы Существуют методы, которые каждый класс наследует от класса Object. Например, каждый объект наследует методы equals() и toString() Метод toString() должен возвратить все данные, содержащиеся в объекте, преобразованными в тип String.
Java, каф.ОСУ, АВТФ34 Многоуровневые производные классы Обычно переопределяют метод toString, чтобы он возвращал соответствующее string-представление для данных, содержащихся в объектах определяемого класса. public String toString() { return ("Имя: + getName () + \nНомер студента: " + Integer.toString(studentNumber)); }
Java, каф.ОСУ, АВТФ35 Многоуровневые производные классы … Student s = new Student (Студент Вася, 2004); System.out.println (s.toString());…
Java, каф.ОСУ, АВТФ36 Многоуровневые производные классы В классе Object этот метод реализован следующим образом: public String toString() { return getClass().getName() + + Integer.toHexString(hashCode()); } То есть возвращает строку, содержащую название класса объекта и его хеш-код в шестнадцатеричном формате.
Java, каф.ОСУ, АВТФ37 Многоуровневые производные классы Logan Pearsall Smith: All my life, as down an abyss without a bottom. I have been pouring van loads of information into that vacancy of oblivion I call my mind Логан Пирсолл Смит: Всю свою жизнь я пытался заполнить бездонную пропасть, которую называл своим разумом