Home  >  Article  >  Java  >  Detailed example of defining abstract properties in Java

Detailed example of defining abstract properties in Java

黄舟
黄舟Original
2017-08-20 09:40:301703browse

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!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn