Beginner, your Java abstract class is a real hassle!

Since I wrote two articles about the nature of science for Xiaobai, I have been a bit out of order and feel it is necessary to continue writing.Because a reader left a message "Encourage" and I said, "Brother, you really break your heart for nothing!"Am I easy?I.

Java's abstract classes come in handy when the task we're going to accomplish is certain, but the exact way to do it requires a subsequent vote.What does this mean?Move a small bench and sit down. Listen to me.

01, 5 Key Points of Abstract Class

1) The abstract keyword is used when defining an abstract class, preceded by the class keyword.

public abstract class AbstractPlayer {
}

As for the naming of abstract classes, Ali's Java development manual emphasizes, "Use Abstract or Base to start the naming of abstract classes", remember.

2) An abstract class cannot be instantiated, but it can have subclasses.

If you try to instantiate with the new keyword, the compiler will error and prompt you that the class is abstract and cannot be instantiated.

The extends keyword allows you to inherit Abstract classes, after which the BasketballPlayer class is a subclass of AbstractPlayer.

public class BasketballPlayer extends AbstractPlayer {
}

3) If a class defines one or more abstract methods, it must be an abstract class.

When an abstract method is defined in a common class (without the abstract keyword modifier), the compiler has two error hints.

First, at the class level, remind you that "this class must be defined by the abstract keyword." The information for or is unnecessary, as shown below.

The second is at the method level, which reminds you that the class in which the abstract method resides is not abstract, as shown below.

4) An abstract class can declare both abstract and specific methods, or it can have no methods at all, but it is not necessary.Like the following:

public abstract class AbstractPlayer {
    abstract void play();

    public void sleep() {
        System.out.println("Athletes need rest, not limit challenge");
    }
}

5) Subclasses derived from abstract classes must implement abstract methods defined in the parent class.For example, the play() method is defined in an abstract class and must be implemented in a subclass.

public class BasketballPlayer extends AbstractPlayer {
    @Override
    void play() {
        System.out.println("I'm Chamberlin and I've been on the basketball court 100 branch");
    }
}

If not, the compiler will remind you that "subclasses must implement Abstract methods", as shown in the following figure.

02. When to use abstract classes

Another concept closely related to abstract classes is the interface, which we will leave to the next article for more details, because there are still a lot of points of knowledge to say.Now all you need is the concept that an interface is an abstraction of behavior and an abstract class is an abstraction of the entire class, including member variables and behaviors.

(Is it a little clear and a little unclear, don't worry, wait for the next article to come out)

In addition to interfaces, there is a concept of a specific class, a common class without abstract modification, as defined in this code below.

public class BasketballPlayer {
   public void play() {
        System.out.println("I'm James, the first person in active service");
    }
}

With interfaces and concrete classes, when should abstract classes be used?

1) We want some common functions to be multiplexed by multiple subclasses.For example, there is a common method sleep() in the AbstractPlayer abstract class that indicates that all athletes need rest, so this method can be reused by subclasses.

public abstract class AbstractPlayer {
    public void sleep() {
        System.out.println("Athletes need rest, not limit challenge");
    }
}

Although the AbstractPlayer class may not be an abstract class, removing the abstract modifier may also satisfy this scenario.However, the AbstractPlayer class may also have one or more abstract methods.

BasketballPlayer inherits the AbstractPlayer class and has the sleep() method.

public class BasketballPlayer extends AbstractPlayer {
}

The BasketballPlayer object can call the sleep() method directly:

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

FootballPlayer inherits the AbstractPlayer class and has the sleep() method.

public class FootballPlayer extends AbstractPlayer {
}

The FootballPlayer object can also call the sleep() method directly:

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

2) We need to define the API in the abstract class and then extend the implementation in the subclass.For example, the AbstractPlayer abstract class has an abstract method, play(), that defines that all athletes can engage in a certain sport, but requires corresponding subclasses to extend the implementation.

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

BasketballPlayer inherits the AbstractPlayer class and extends to implement its own play() method.

public class BasketballPlayer extends AbstractPlayer {
    @Override
    void play() {
        System.out.println("I'm Chamberlin and I've been on the basketball court 100 Score,");
    }
}

FootballPlayer inherits the AbstractPlayer class and extends to implement its own play() method.

public class FootballPlayer extends AbstractPlayer {
    @Override
    void play() {
        System.out.println("I am C Ro, I can catch a headball at any height");
    }
}

3) If the relationship between parent and child conforms to the hierarchical relationship of is-a, abstract classes can be used, such as basketball players and football players.

03. Specific examples

To further illustrate the nature of abstract classes, let's look at a specific example.Suppose you have a file with a very simple content - "Hello World". Now you need a reader to read the content, preferably in uppercase or lowercase.

At this point, it's best to define an abstract class, such as 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 is a file path, decorated with protected, indicating that the member variable can be accessed by subclasses when needed.

The readFile() method is used to read files, and the abstract method mapFileLine() is called inside the body of the method, which requires subclasses to extend the way uppercase and lowercase are implemented.

As you can see, BaseFileReader is reasonably designed and easy to extend, and subclasses just need to focus on specific case implementations.

Lowercase:

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

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

Uppercase:

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

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

You can see that the code that reads from one line to another in a file is multiplexed by subclasses, the common method readFile() defined in the abstract BaseFileReader class.At the same time, subclasses just need to focus on what they do, LowercaseFileReader reads the file contents in lowercase and UppercaseFileReader reads the file contents in uppercase.

Next, let's create a new test class, 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());
    }
}

There is a text file named helloworld.txt in the resource directory of the project.

The URI path to the file can be obtained by ClassLoader.getResource(), and the text content can then be read using LowercaseFileReader and UppercaseFileReader.

The output is as follows:

[hello world]
[HELLO WORLD]

Well, my dear reader friend, that's all about this article.Does it feel like the cognitive boundaries have widened again?

I'm Silence King, an interesting programmer.If you find the article helpful, please WeChat to search for "Silence King II" for the first time to read, reply to [666] and more 500G HD instructional videos (categorized) that I have prepared for you.

This paper GitHub Already included, there are complete test points for factory interviews. Welcome to Star.

Originality is not easy. Don't give me a blank ticket. Please give me a compliment for this article. This will be the strongest motivation for me to write more good articles.

Tags: Java REST github

Posted on Tue, 05 May 2020 21:00:24 -0400 by br3nn4n