Abstract关键字通常用在类和方法中,将某些行为的实现委托给子类。由于Java不支持抽象属性,如果您尝试将类属性标记为抽象属性,则会出现编译时错误。在本教程中,我们将研究两种定义抽象属性的方法,这些属性可以在不使用Abstract关键字的情况下由子类设置。实际案例假设我们要实现一个记录交易的日志模块来记录具体交易的信息。我们希望这个模块是抽象的,以便我们可以实现不同的日志记录方法,例如:记录到文件或数据库。我们的引擎使用预定义的分隔符来连接日志中的信息并将其存储在字符串中。使用哪种分隔符取决于日志记录规则,例如可以使用字符“,”来分隔日志记录信息的不同部分。因此,分隔符对我们的引擎来说似乎是抽象的,需要由每个日志记录规则明确定义。下面我提供两种方式将分隔符的定义委托给子类。在抽象类中定义参数化构造函数在抽象类中定义动态属性的第一种方法是定义参数化构造函数。所以我们可以像这样实现这个引擎:ret}publicvoidendTransaction(Transactiont){longprocessingTime=System.currentTimeMillis()-t.getStartTime();StringBuilderlogBu??ilder=newStringBuilder();logBu??ilder.append(t.getStartTime());//注意使用this.separatorlogBu??ilder.append(this.separator);logBu??ilder.append(processingTime);logBu??ilder.append(this.separator);logBu??ilder.append(t.getData());Stringresult=logBu??ilder.toString();writeTransaction(result);}}在抽象类中定义参数化构造时一个函数,子类将被迫定义自己的构造函数并调用super()。这样我们就可以强制分隔符属性依赖于正在使用的日志记录机制。请注意,我们的引擎实现了所有日志机制共有的静态行为:startTransaction()、endTransaction(),同时将动态行为writeTransaction()交给子类来实现。现在,如果我们想创建一个事务管理器,并用它来记录日志内容到一个文件中,我们可以这样定义它:){System.out.println("Thefollowingtransactionhasjustfinished:");System.out.println(result);}}接下来,做一个测试看看代码是如何工作的publicstaticvoidmain(String[]args)throwsInterruptedException{//wepasstheseparatorexplicitlyintheconstructorTransactionManagertransactionManager=newTransactionManagerFS(",");Transactiontransaction=transactionManager.startTransaction();transaction.setData("Thisisatesttransaction!!");Thread.sleep(1500);transactionManager.endTransaction(transaction);}输出:以下事务刚刚完成:1502179140689,1501,这是一笔交易!!通过getter方法传递定界符另一种实现动态属性的方法是定义一个抽象的getter方法,该方法根据当前的日志记录机制检索所需的定界符。在我们的引擎中,当需要分隔符的时候,可以通过调用这个getter方法来获取。接下来我们将引导修改成这样:publicabstractclassTransactionManager{publicabstractStringgetSeperator();publicabstractvoidwriteTransaction(Stringresult);publicTransactionstartTransaction(){Transactiontransaction=newTransaction(System.currentTimeMillis());returntransaction;}publicvoidendTransaction(Transactiont){longprocessingTime=System.currentTimeMillis().currentTimeMillis-t.getStartTime();StringBuilderlogBu??ilder=newStringBuilder();logBu??ilder.append(t.getStartTime());//注意使用getSeparator()logBu??ilder.append(getSeperator());logBu??ilder.append(processingTime);logBu??ilder.append(getSeperator());logBu??ilder.append(t.getData());Stringresult=logBu??ilder.toString();writeTransaction(result);}}另外修改TransactionManagerFS如下:publicclassTransactionManagerFSextendsTransactionManager{@OverridepublicStringgetSeperator(){return",";}@OverridepublicvoidwriteTransaction(Stringresult){System.out.println("Thefollowingtransactionhasjustfinished:");System.out.println(result);}}然后,修改main使用新的实现并确保你得到正确的结果;transactionThis!transaction.setData(");Thread.sleep(1500);transactionManager.endTransaction(transaction);}输出:以下交易刚刚完成:1502179140689,1501,Thisisatesttransaction!!
