This article mainly introduces relevant information about how to define an abstract attribute example in Java. Friends who need it can refer to it
Preface
This article mainly introduces to you the relevant content of defining an abstract attribute in Java, and shares it for your reference and study. I won’t say much below, let’s take a look at the detailed introduction:
Abstract keyword is usually used in classes and methods to delegate the implementation of certain behaviors to subclasses. Since Java does not support abstract properties, you will get a compile-time error if you try to mark a class property as abstract.
In this tutorial, we will introduce two methods of defining abstract properties that can be set by subclasses without using the Abstract keyword.
Practical Case
Suppose we want to implement a transaction log module to record specific transaction information. We want this module to be abstract so that we can implement different logging methods, such as logging to a file or database.
Our engine uses predefined delimiters to concatenate the information in the log and store it in a String. Which delimiter should be used depends on the logging rules. For example, the character "," can be used to separate different parts of the information in the log record.
Therefore, delimiters appear to be abstract to our engine and need to be explicitly defined by each logging rule.
Below I provide two ways to delegate the definition of separators to subclasses.
Defining a constructor with parameters in an abstract class
The first way to define dynamic properties in an abstract class is : Define a constructor with one parameter.
So we can implement this engine like this:
// TransactionManager.java public abstract class TransactionManager { private String separator; public TransactionManager(String separator) { this.separator = separator; } public abstract void writeTransaction(String result); public Transaction startTransaction() { Transaction transaction = new Transaction(System.currentTimeMillis()); return transaction; } public void endTransaction(Transaction t) { long processingTime = System.currentTimeMillis() - t.getStartTime(); StringBuilder logBuilder = new StringBuilder(); logBuilder.append(t.getStartTime()); // Notice the use of this.separator logBuilder.append(this.separator); logBuilder.append(processingTime); logBuilder.append(this.separator); logBuilder.append(t.getData()); String result = logBuilder.toString(); writeTransaction(result); } }
When defining a constructor with parameters in an abstract class, the subclass will be forced to define itself constructor and call super()
. This way we can force the separator attribute to depend on the logging mechanism in use.
Note: Our engine implements static behavior common to all logging mechanisms: startTransaction()
, endTransaction()
, while leaving the dynamic behavior writeTransaction()
to subclasses for implementation.
Now, if we want to create a transaction manager and use it to record the log content to a file, then we can define it like this:
public class TransactionManagerFS extends TransactionManager{ // The IDE forces you to implement constructor. public TransactionManagerFS(String separator) { super(separator); } @Override public void writeTransaction(String result) { System.out.println("The following transaction has just finished: " ); System.out.println(result); } }
Next do a test to see how the code works
public static void main(String[] args) throws InterruptedException { // we pass the separator explicitly in the constructor TransactionManager transactionManager = new TransactionManagerFS(","); Transaction transaction = transactionManager.startTransaction(); transaction.setData("This is a test transaction !!"); Thread.sleep(1500); transactionManager.endTransaction(transaction); }
Output:
The following transaction has just finished: 1502179140689,1501,This is a test transaction !!
Pass the delimiter through the getter method
Another way to implement dynamic properties is by defining an abstract getter method, which is based on the current log record Mechanism to retrieve the required delimiter. In our engine, when a delimiter is needed, it can be obtained by calling this getter method.
Next we modify the engine like this:
public abstract class TransactionManager { public abstract String getSeperator(); public abstract void writeTransaction(String result); public Transaction startTransaction() { Transaction transaction = new Transaction(System.currentTimeMillis()); return transaction; } public void endTransaction(Transaction t) { long processingTime = System.currentTimeMillis() - t.getStartTime(); StringBuilder logBuilder = new StringBuilder(); logBuilder.append(t.getStartTime()); // Notice the use of getSeparator() logBuilder.append(getSeperator()); logBuilder.append(processingTime); logBuilder.append(getSeperator()); logBuilder.append(t.getData()); String result = logBuilder.toString(); writeTransaction(result); } }
In addition, modify TransactionManagerFS as follows:
public class TransactionManagerFS extends TransactionManager{ @Override public String getSeperator() { return ","; } @Override public void writeTransaction(String result) { System.out.println("The following transaction has just finished: " ); System.out.println(result); } }
Then, modify main to use the new implementation and ensure you get the correct results.
public static void main(String[] args) throws InterruptedException { // The separator is defined implicitly using getSeparator() method of the manager TransactionManager transactionManager = new TransactionManagerFS(); Transaction transaction = transactionManager.startTransaction(); transaction.setData("This is a test transaction !!"); Thread.sleep(1500); transactionManager.endTransaction(transaction); }
Output:
The following transaction has just finished: 1502179140689,1501,This is a test transaction !!
Summary
The above is the detailed content of Detailed example of defining abstract properties in Java. For more information, please follow other related articles on the PHP Chinese website!