Загрузка...

Абстрактные классы в Java

Пометьте родительский класс как abstract, когда он должен оставить хотя бы один метод без тела для заполнения потомками. Напишите abstract class Machine с abstract void horn(); и обычным методом park, который печатает park. Напишите class Truck extends Machine и дайте horn тело, которое печатает honk. В Yard.java создайте Truck, вызовите t.horn(), затем вызовите t.park(). Скомпилируйте через javac Yard.java и запустите java Yard. На экране должны быть honk, затем park. Вторая демо добавляет Car, чтобы два потомка заполняли horn по-разному. Polymorphism оставьте для следующей страницы — этот урок про незавершённый метод родителя и потомка, который его дописывает.

Заполните abstract-метод у потомка

Страница enum перечисляла фиксированные имена. Эта страница намеренно оставляет метод незавершённым. Откройте Yard.java. Держите имя public-класса Yard. Удалите оставшиеся демо enum Level, если они хоронят историю abstract, файлы Signal / implements, демо путей и любой клавиатурный Scanner. Программа не должна ждать ввода. Строка import не нужна.
Объявите abstract-родителя над другими типами:
abstract class Machine {
abstract void horn();
void park() {
System.out.println("park");
}
}
Abstract-метод заканчивается точкой с запятой и не имеет тела { }. Обычный метод park сохраняет полное тело, чтобы каждый потомок мог его переиспользовать.
Объявите потомка через extends Machine. Заполните horn:
void horn() {
System.out.println("honk");
}
Вы должны заполнить каждый abstract-метод, перечисленный у родителя. На этой странице это только horn. Не пишите new Machine() в main — abstract-класс не создаётся как объект сам по себе.
Внутри Yard.main:
Truck t = new Truck();
t.horn();
t.park();
Первый вызов выполняет тело у Truck. Второй вызов выполняет общее тело у Machine.

Yard Truck fills abstract horn then park

java
abstract class Machine {
    abstract void horn();
    void park() {
        System.out.println("park");
    }
}

class Truck extends Machine {
    void horn() {
        System.out.println("honk");
    }
}

public class Yard {
    public static void main(String[] args) {
        Truck t = new Truck();
        t.horn();
        t.park();
    }
}

Из папки, где лежит Yard.java, запустите javac Yard.java. Когда скобки, фигурные скобки и точки с запятой совпадают, javac не пишет свою строку. Затем запустите java Yard — не java Yard.java. Уберите окончание .java из команды запуска. Держите один public-класс в файле, чтобы имя совпадало с Yard. Вспомогательные типы Machine и Truck на этой учебной форме остаются без public.
Экран показывает honk, затем park. Пройдите запуск один раз. Java начинает с Yard.main. new Truck() создаёт truck, который завершил abstract horn. t.horn() печатает honk. t.park() печатает park из родительского тела, которое уже было. Незавершённый метод существовал только как требование, пока потомок не написал тело.
Если javac отказывает, проверьте три вещи. Во-первых, строка родительского класса должна говорить abstract class Machine. Во-вторых, незавершённый метод должен говорить abstract и заканчиваться на ;. В-третьих, Truck действительно должен написать horn с телом. Если вы всё ещё видите MEDIUM из файла enum, переключитесь на учебный abstract-файл и снова запустите java Yard. Если попробовать new Machine(), javac отказывает — на этой странице так и ожидается.
Произнесите правило вслух, глядя на экран: abstract-родитель называет недостающий метод, потомок заполняет его, общие методы всё ещё выполняются. Пока не изобретайте длинный парад polymorphism с множеством переменных родительского типа. Эта история ждёт следующего урока.

Два потомка заполняют horn по-разному

Вторая программа держит тот же abstract Machine. Truck по-прежнему печатает honk. Новый Car печатает beep. main создаёт обоих, вызывает каждый horn, затем вызывает park у truck.

Yard Truck and Car fill horn then park

java
abstract class Machine {
    abstract void horn();
    void park() {
        System.out.println("park");
    }
}

class Truck extends Machine {
    void horn() {
        System.out.println("honk");
    }
}

class Car extends Machine {
    void horn() {
        System.out.println("beep");
    }
}

public class Yard {
    public static void main(String[] args) {
        Truck t = new Truck();
        Car c = new Car();
        t.horn();
        c.horn();
        t.park();
    }
}

Скомпилируйте через javac Yard.java, затем запустите java Yard. Экран показывает honk, затем beep, затем park. Каждый потомок заполнил то же abstract-имя своей печатью. Общее тело park по-прежнему приходит из Machine. Вы всё ещё никогда не пишете new Machine().
Прочитайте родителя ещё раз: один abstract-метод, один обычный метод. Прочитайте потомков: каждый пишет horn, никто на этой странице не переписывает park. Это разделение — учебный пункт. Если опустить horn у Car, пока Car extends Machine, javac отказывает, потому что каждый abstract-метод должен быть заполнен.
Если рядом ещё лежат демо enum, держите их как историю. Для этого урока запускайте учебный abstract-файл, чтобы экран показывал заполнения методов, а не MEDIUM. Если javac жалуется на дублирующие public-классы, оставьте public только у Yard.

Сравнение с enum и interfaces

На странице enum Level перечислял фиксированные имена. На странице interfaces implements заполнял пустые методы интерфейса. На этой странице abstract class плюс extends оставляют метод класса незавершённым, пока потомок не напишет тело. Вы по-прежнему компилируете Yard.java и запускаете java Yard. Новые токены — abstract class, abstract void horn(); и потомок, который даёт тело, переиспользуя park.
Если ещё открыт оставшийся файл enum Level, вы увидите константы и, возможно, switch. Переключитесь на abstract-файл, чтобы сверху было abstract class Machine, а main создавал Truck. Держите демо polymorphism, которые только переставляют переменные родительского типа, вне этой страницы. Держите клавиатурный ввод вне этой страницы.

Что это оставляет для polymorphism

Эта страница завершает abstract-методы у конкретных потомков. Следующая страница показывает polymorphism, где одна переменная родительского типа может держать разные объекты-потомки и вызывать подходящее тело метода. Оставайтесь здесь с abstract-родителями и заполненными потомками. Пока не требуйте список переменных Machine, указывающих на многих потомков.
Когда позже будете писать демо polymorphism, вы часто всё ещё начнёте с имени abstract или обычного родительского метода. Считайте эту страницу половиной незавершённого метода той соседней истории. Доведите обе Yard-демо до автоматичности — honk затем park, а потом honk, beep, park — прежде чем открывать урок polymorphism.

Перед polymorphism

Вы можете объявить abstract class Machine, заполнить horn у Truck и увидеть honk, затем park. Вы можете добавить Car с собственным horn и увидеть honk, затем beep, затем park. Компилируйте Yard.java и запускайте java Yard для каждой сохранённой демо по очереди. Потомок завершил abstract-метод. Следующая страница — polymorphism, где вызовы через ссылку родительского типа выбирают тело потомка.
Держите демо с одним truck для ясного abstract-заполнения плюс общего park. Держите демо с двумя потомками для ясной пары заполнений. Держите файлы парада polymorphism вне этой страницы. Эти три привычки — контрольная точка перед движением дальше. Когда после new Truck() появляется honk перед park, abstract-классы сделали работу этого урока, и вы готовы к следующей теме о polymorphism.
Последний проход по папке: один public Yard, один abstract Machine, конкретные потомки, заполняющие horn, без new Machine(), без ожидания клавиатуры. Ещё раз запустите javac Yard.java и java Yard на демо, которую держите открытой. Если экран всё ещё печатает заполнения, которые вы написали, abstract-контракт крепок, и курс может перейти к polymorphism на следующей странице.

🧠 Проверьте Свои Знания

Готов к Началу

Проверьте Свои Знания

Бросьте себе вызов с помощью этой интерактивной викторины и узнайте, насколько хорошо вы понимаете тему

❓
6
Вопросы
🎯
70%
Для Прохождения
♾️
∞
Время
🔄
∞
Попытки

📝 Инструкции

  • Внимательно прочитайте каждый вопрос
  • Выберите лучший ответ на каждый вопрос
  • Вы можете пересдавать тест столько раз, сколько захотите
  • Ваш прогресс будет показан вверху