Xiaobai, абстрактный класс Java, который вы хотите, просто душераздирающий!

Java

Поскольку я написал две научно-популярные статьи для Xiaobai, я почувствовал себя немного неуправляемым и почувствовал, что необходимо продолжать писать. Поскольку читатель оставил «обнадеживающее» сообщение, я сказал: «Второй брат, ты действительно разбил свое сердце из-за Сяобая!» Легко ли мне? Я.

Абстрактные классы Java пригодятся, когда задача, которую мы хотим выполнить, определена, но конкретный метод требует последующего собрания для голосования. Как понять эту фразу? Отодвиньте маленькую скамейку, сядьте и послушайте, что я вам скажу.

01. 5 ключевых моментов абстрактных классов

1) При определении абстрактных классов вам нужно использовать ключевые словаabstract, вставитьclassперед ключевым словом.

public abstract class AbstractPlayer {
}

Что касается именования абстрактных классов, Руководство по разработке Java, произведенное Али подчеркивает, что «имена абстрактных классов должны начинаться с абстрактных или базы», ​​помните.

2) Абстрактный класс не может быть создан, но может иметь подклассы.

попробуй пройтиnewЕсли ключевое слово создано, компилятор сообщит об ошибке с сообщением «Класс является абстрактным и не может быть создан».

пройти черезextendsКлючевые слова могут наследовать абстрактные классы.После наследования класс BasketballPlayer является подклассом AbstractPlayer.

public class BasketballPlayer extends AbstractPlayer {
}

3) Если класс определяет один или несколько абстрактных методов, то этот класс должен быть абстрактным классом.

Когда в нормальном классе (без использованияabstractмодификация ключевого слова) определяет абстрактный метод, компилятор выдаст два сообщения об ошибках.

Первый — на уровне класса, напоминающий вам, что «этот класс должен пройтиabstractОпределение ключевого слова», информация о или не требуется, см. рисунок ниже.

Второй — на уровне метода, напоминая вам, что «класс, в котором находится абстрактный метод, не является абстрактным», см. рисунок ниже.

4) Абстрактный класс может объявлять абстрактные и конкретные методы одновременно, а может вообще не иметь методов, но это не обязательно. Как следующее:

public abstract class AbstractPlayer {
    abstract void play();

    public void sleep() {
        System.out.println("运动员也要休息而不是挑战极限");
    }
}

5) Подклассы, производные от абстрактного класса, должны реализовывать абстрактные методы, определенные в родительском классе. Например, абстрактный класс определяетplay()метод должен быть реализован в подклассах.

public class BasketballPlayer extends AbstractPlayer {
    @Override
    void play() {
        System.out.println("我是张伯伦,篮球场上得过 100 分");
    }
}

Если он не реализован, компилятор напомнит вам, что «подклассы должны реализовывать абстрактные методы», см. рисунок ниже.

02. Когда использовать абстрактные классы

Существует еще одно понятие, тесно связанное с абстрактными классами, а именно интерфейс, подробное описание которого мы оставим до следующей статьи, потому что еще предстоит сказать много знаний. Вам нужно только иметь такое понятие сейчас, интерфейс — это абстракция поведения, а абстрактный класс — это абстракция всего класса (включая переменные-члены и поведение).

(Вы немного понимаете и немного не понимаете, не волнуйтесь, просто дождитесь выхода следующей статьи)

Помимо интерфейса, есть еще одно понятие, которое является специфическим классом, т. е. не проходитabstractУкрашенный обычный класс, см. определение в следующем коде.

public class BasketballPlayer {
   public void play() {
        System.out.println("我是詹姆斯,现役第一人");
    }
}

Существуют интерфейсы и конкретные классы, так когда же нам следует использовать абстрактные классы?

1) Мы хотим, чтобы некоторые общие функции повторно использовались несколькими подклассами. Например, в абстрактном классе AbstractPlayer есть общий методsleep(), указывая на то, что всем спортсменам нужно отдыхать, то этот метод может быть повторно использован подклассами.

public abstract class AbstractPlayer {
    public void sleep() {
        System.out.println("运动员也要休息而不是挑战极限");
    }
}

Хотя класс AbstractPlayer может и не быть абстрактным — поставьтеabstractМодификатор также может встретить эту сцену. Но класс AbstractPlayer может иметь один или несколько абстрактных методов.

BasketballPlayer наследует класс AbstractPlayer и имеетsleep()метод.

public class BasketballPlayer extends AbstractPlayer {
}

Объект BasketballPlayer можно вызывать напрямуюsleep()метод:

BasketballPlayer basketballPlayer = new BasketballPlayer();
basketballPlayer.sleep();

FootballPlayer наследует класс AbstractPlayer и имеетsleep()метод.

public class FootballPlayer extends AbstractPlayer {
}

Объекты FootballPlayer также можно вызывать напрямую.sleep()метод:

FootballPlayer footballPlayer = new FootballPlayer();
footballPlayer.sleep();

2) Нам нужно определить API в абстрактном классе, а затем расширить реализацию в подклассе. Например, в абстрактном классе AbstractPlayer есть абстрактный метод.play(), который определяет, что все спортсмены могут заниматься определенным видом спорта, но требует соответствующих подклассов для расширения реализации.

public abstract class AbstractPlayer {
    abstract void play();
}

BasketballPlayer наследует класс AbstractPlayer и расширяет собственный класс.play()метод.

public class BasketballPlayer extends AbstractPlayer {
    @Override
    void play() {
        System.out.println("我是张伯伦,我篮球场上得过 100 分,");
    }
}

FootballPlayer наследует класс AbstractPlayer и расширяет собственный класс.play()метод.

public class FootballPlayer extends AbstractPlayer {
    @Override
    void play() {
        System.out.println("我是C罗,我能接住任意高度的头球");
    }
}

3) Если отношения между родительским классом и подклассом соответствуютis-aИерархические отношения, вы можете использовать абстрактные классы, например, баскетболисты являются игроками, футболисты являются игроками.

03. Конкретные примеры

Чтобы дополнительно продемонстрировать свойства абстрактных классов, давайте рассмотрим конкретный пример. Допустим, теперь есть файл с очень простым содержимым — «Hello World», и теперь читателю нужно прочитать содержимое, желательно в верхнем или нижнем регистре.

В настоящее время лучше определить абстрактный класс, такой как BaseFileReader:

public abstract class BaseFileReader {
    protected Path filePath;

    protected BaseFileReader(Path filePath) {
        this.filePath = filePath;
    }

    public List<String> readFile() throws IOException {
        return Files.lines(filePath)
                .map(this::mapFileLine).collect(Collectors.toList());
    }

    protected abstract String mapFileLine(String line);
}

filePath — это путь к файлу, помеченный как protected, указывающий, что к переменной-члену могут обращаться подклассы, когда это необходимо.

readFile()Метод используется для чтения файла и называется абстрактным методом.mapFileLine()- Требует, чтобы подклассы расширяли способ реализации case.

Видите ли, BaseFileReader разработан очень разумно и легко расширяется, а подклассы должны сосредоточиться только на реализации конкретного случая.

Нижний регистр:

public class LowercaseFileReader extends BaseFileReader {
    protected LowercaseFileReader(Path filePath) {
        super(filePath);
    }

    @Override
    protected String mapFileLine(String line) {
        return line.toLowerCase();
    }
}

Верхний регистр:

public class UppercaseFileReader extends BaseFileReader {
    protected UppercaseFileReader(Path filePath) {
        super(filePath);
    }

    @Override
    protected String mapFileLine(String line) {
        return line.toUpperCase();
    }
}

Видите ли, код, который читает строку содержимого по строке из файла, повторно используется подклассом - обычный метод, определенный в классе BaseFileReader Class Class.readFile(). В то же время подклассы нужно только сосредоточиться на собственной работе. LowerCaseFileReader считывает содержимое файла в нижнем регистре, и верхний регистрФилереатор читает содержимое файла в верхнем регистре.

Далее создадим новый тестовый класс FileReaderTest:

public class FileReaderTest {
    public static void main(String[] args) throws URISyntaxException, IOException {
        URL location = FileReaderTest.class.getClassLoader().getResource("helloworld.txt");
        Path path = Paths.get(location.toURI());
        BaseFileReader lowercaseFileReader = new LowercaseFileReader(path);
        BaseFileReader uppercaseFileReader = new UppercaseFileReader(path);
        System.out.println(lowercaseFileReader.readFile());
        System.out.println(uppercaseFileReader.readFile());
    }
}

В каталоге ресурсов проекта есть текстовый файл с именем helloworld.txt.

в состоянии пройтиClassLoader.getResource()чтобы получить путь URI к файлу, а затем вы можете использовать LowercaseFileReader и UppercaseFileReader для чтения текстового содержимого.

Результат выглядит следующим образом:

[hello world]
[HELLO WORLD]

Ну вот, дорогие мои читатели, и все содержание статьи. Вы не чувствуете, что они узнали? Я был молчаливым королем, одним интересным программистом. Если вы считаете, что ваша статья немного поможет, поищите в WeChat »Тихий король 2"Читал в первый раз.

эта статьяGitHubОн был включен, и есть полные тестовые площадки для интервью на крупных заводах Добро пожаловать в Star.

Оригинальность непроста, не просите пустой билет, пожалуйста, поставьте лайк этой статье, что будет моей сильнейшей мотивацией писать больше качественных статей.