Abstract methods and abstract classes
Abstract classes: classes modified with abstract modifiers, such as:
public abstract class GeneralService { }
Abstract method: Abstract modifier modified method, abstract method can not have method body, such as:
public abstract void service();
The rules for abstract classes and methods are as follows:
- Must be modified with abstract modifiers
- Abstract classes do not necessarily contain Abstract methods, but classes containing abstract methods must be abstract classes.
- Abstract classes cannot be instantiated
- The constructor of an abstract class cannot be used to create objects, but is mainly used to be called by its subclasses.
The following defines a Shape Abstract class:
/** * Define an abstract class to describe the "shape" of abstract concepts */ public abstract class Shape { // Shape color private String color; public String getColor() { return color; } public void setColor(String color) { this.color = color; } // Parametric constructor public Shape(String color) { this.color = color; } // Define an abstract method for calculating perimeter public abstract double calPerimeter(); }
The Shape class above contains an abstract method, calPerimeter(), so the Shape class can only be an abstract class. Shape classes contain both initialization blocks and constructors, but these are not called when creating Shape objects, but when creating its subclass objects.
Next, we define a Triangle class and a Circle class to inherit the Shape class and implement the abstract method calPerimeter() in Shape.
/** * Define a triangle class that inherits from the shape class */ public class Triangle extends Shape { // Define three edges of a triangle private double a; private double b; private double c; public Triangle(String color, double a, double b, double c) { super(color); this.a = a; this.b = b; this.c = c; } @Override public double calPerimeter() { return a + b + c; } }
/** * Define a circular class that inherits from the shape class */ public class Circle extends Shape { // Define the radius of a circle private double radius; public Circle(String color, double radius) { super(color); this.radius = radius; } @Override public double calPerimeter() { return 2 * Math.PI * this.radius; } }
Shape (shape) class is an abstract concept. Triangle (triangle) class and Circle (circle) class are the representations of Shape. They both implement Shape's calPerimeter() method. The formulas for calculating perimeter are different.
The following are the test classes:
/** * Test class */ public class Test { public static void main(String[] args) { Shape s1 = new Triangle("yellow", 3.0, 4.0, 5.0); Shape s2 = new Circle("gules", 3); System.out.println("Triangle s1 Color:" + s1.getColor() + ",Perimeter:" + s1.calPerimeter()); System.out.println("circular s2 Color:" + s2.getColor() + ",Perimeter:" + s2.calPerimeter()); } }
Output results:
Triangle s1 color: yellow, circumference: 12.0 Round s2 color: red, circumference: 18.84955592153876
- When using abstract to modify a class, it means that the class is abstract and can only be inherited; when using abstract to modify a method, it means that the method must be implemented (rewritten) by its subclasses.
- Final-modified classes cannot be inherited, final-modified methods cannot be overridden, so final and abstract cannot be used simultaneously.
- When using static to decorate a method, it means that the method is a class method, which can be called directly by the class without creating objects. But if the method is defined as abstract, it will lead to errors when calling the method through the class (calling a method without a method body will certainly cause errors), so static and abstract cannot modify a method at the same time.
- The abstract keyword modification method must be overridden by its subclasses in order to be meaningful. Therefore, the abstract method cannot be defined as private access rights, that is, private and abstract can not modify a method at the same time.
The role of abstract classes
Abstract class is the parent class abstracted from many concrete classes. It has a higher level of abstraction, describing the commonness of a group of things.
Abstract classes are common templates for many subclasses. Subclasses are extended and modified on the basis of abstract classes. However, subclasses generally retain the behavior of abstract classes.
Template Method Patterns
If you write an abstract parent class, the parent class provides a common method for multiple subclasses and leaves one or more methods to its subclasses to implement. This is the template pattern, which is a very common and simple design pattern.
A slightly more professional definition is:
Template method pattern defines the skeleton of an algorithm in a method and delays some steps to subclasses. Template method enables subclasses to redefine some steps in the algorithm without changing the structure of the algorithm.
Here's another example of a template approach pattern, in which we divide the cooking process into three steps:
- Spare parts
- Cook
- Loading
These three parts are the skeleton of the algorithm. However, different dishes need different ingredients, cooking methods, and how to plate. When making different dishes, different implementations are needed.
Let's write an abstract cooking parent class with the following code:
/** * Define the abstract class of cooking */ public abstract class DodishTemplate { /** * Template method encapsulates the cooking algorithm * Modify with final keywords to avoid subclasses modifying the order of algorithms * The template method defines a series of steps, each represented by a method. */ protected final void dodish(){ this.preparation(); this.doing(); this.sabot(); } /** * Spare parts */ public abstract void preparation(); /** * Cook */ public abstract void doing(); /** * Loading */ public abstract void sabot(); }
Next, we define how to make scrambled eggs with tomatoes and braised meat with red sauce and realize the abstract method in the parent class.
/** * Making scrambled eggs with tomatoes */ public class EggsWithTomato extends DodishTemplate{ @Override public void preparation() { System.out.println("Wash and cut tomatoes and beat eggs."); } @Override public void doing() { System.out.println("Pour the eggs into the pot and stir-fry the tomatoes."); } @Override public void sabot() { System.out.println("Scrambled eggs and tomatoes are put into a dish and sprinkled with scallions."); } }
/** * Making red-roasted meat */ public class Bouilli extends DodishTemplate{ @Override public void preparation() { System.out.println("Cut pork and potatoes.*"); } @Override public void doing() { System.out.println("Stir-fry the cut pork in the pan for a while and then pour the potatoes into the pan and stew."); } @Override public void sabot() { System.out.println("Pour the cooked red meat into a bowl and sprinkle with white sesame seeds."); } }
In the test class, we cook dishes:
public class App { public static void main(String[] args) { DodishTemplate eggsWithTomato = new EggsWithTomato(); eggsWithTomato.dodish(); System.out.println("-----------------------------"); DodishTemplate bouilli = new Bouilli(); bouilli.dodish(); } }
Operation results:
Wash and cut tomatoes and beat eggs. Pour the eggs into the pot and stir-fry the tomatoes. Scrambled eggs and tomatoes are put into a dish and sprinkled with scallions. ----------------------------- Cut pork and potatoes. Stir-fry the cut pork in a pan for a while and then pour the potatoes into the pan and stew. Pour the cooked red meat into a bowl and sprinkle with white sesame seeds.
From this example, we can see that the DodishTemplate class defines a general algorithm for cooking, while some specific implementation details are deferred to its subclasses (EggsWithTomato and Bouilli). That is, the template method defines the steps of an algorithm and allows subclasses to provide implementations for one or more steps.