代码之家  ›  专栏  ›  技术社区  ›  Brian

如何用内部类正确实现Java接口?

  •  1
  • Brian  · 技术社区  · 6 年前

    我有一段代码将事件写入日志文件:

    Date rightNow = new Date();
    File logfile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS), ("MyLogfile" + fileSDF.format(rightNow) + ".txt"));
    FileOutputStream fos;
    boolean documents_directory_exists = logfile.getParentFile().exists();
    boolean documents_directory_created = true;
    if(!documents_directory_exists) documents_directory_created = logfile.getParentFile().mkdirs();
    if(documents_directory_created){
        try {
            fos = new FileOutputStream(logfile, true);
            fos.write(new LogEntry(timestampSDF.format(rightNow), boolean01, someInt, boolean02).toString().getBytes());
            fos.close();
        } catch (IOException ioe) {
            Log.e(SomeClass.class.getName(), String.format(Locale.US, "%s %s", Constants.DEFAULT_FILE_ERROR_MESSAGE, ioe.getMessage()));
        }
    } else {
            Log.e(SomeClass.class.getName(), String.format(Locale.US, "%s %s", Constants.DEFAULT_FILE_ERROR_MESSAGE, "Cannot create the necessary directories."));
    }
    

    我把这个代码放在多个地方,所以我想我应该把它放在一个界面上,这样我的代码就更干净了。所以我创建了这个界面:

    public interface LogWriter {
        void writeLog(LogEntry logEntry);
    }
    

    其中LogEntry是:

    public class LogEntry{
        private String timestamp;
        private boolean booean01;
        private int someInt;
        private boolean boolean02;
    
        public LogEntry(timestamp, boolean01, someInt, boolean02){
            this.timestamp = timestamp;
            this.boolean01= boolean01;
            this.someInt= someInt;
            this.boolean02= boolean02;
        }
    
        // Getters and Setters
    }
    

    public interface LogWriter {
        void writeLog(LogEntry logEntry);
    
        class WriteMeToTheLog {
            LogEntry logEntry;
    
            private static final SimpleDateFormat fileSDF = new SimpleDateFormat(Constants.ACCESS_LOGFILE_NAME_FORMAT);
    
            public WriteMeToTheLog(LogEntry logEntry) {
                this.logEntry = logEntry;
            }
    
            public void write(){
                 Date rightNow = new Date();
                 File logfile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS), ("MyLogfile" + fileSDF.format(rightNow) + ".txt"));
                 FileOutputStream fos;
                 boolean documents_directory_exists = logfile.getParentFile().exists();
                 boolean documents_directory_created = true;
                 if(!documents_directory_exists) documents_directory_created = logfile.getParentFile().mkdirs();
                 if(documents_directory_created){
                     try {
                         fos = new FileOutputStream(logfile, true);
                         fos.write(new LogEntry(timestampSDF.format(rightNow), boolean01, someInt, boolean02).toString().getBytes());
                         fos.close();
                     } catch (IOException ioe) {
                         Log.e(SomeClass.class.getName(), String.format(Locale.US, "%s %s", Constants.DEFAULT_FILE_ERROR_MESSAGE, ioe.getMessage()));
                    }
                } else {
                    Log.e(SomeClass.class.getName(), String.format(Locale.US, "%s %s", Constants.DEFAULT_FILE_ERROR_MESSAGE, "Cannot create the necessary directories."));
                }
            }
        }
    }
    

    这就是我要去的地方 迷路的。

    在我拥有原始代码块的一个类中,我实现了这个新接口:

    public class OneOfMyClasses extends BaseClass implements LogWriter {
        public myMethod(){
            // This is where I had the original block of code
            // WHAT DO I DO HERE NOW???
        }
    
        @Override
        public void writeLog(){
            Date rightNow = new Date();
            writeMeToTheLog(new LogEntry(timestampSDF.format(rightNow), boolean01, someInt, boolean02).toString().getBytes());
            writeMeToTheLog.write();
        }
    }
    

    如何使用此新功能?

    1 回复  |  直到 6 年前
        1
  •  0
  •   davidxxx    6 年前

    我想保持我的代码非常干净,所以我想做所有的文件 接口中的I/O,所以我创建了一个内部类

    在接口中声明类不需要“干净”。

    所有这些都是违反直觉的。类是一个实现,接口是一个API。API声明实现结构听起来不太好。

    关于你的问题,我认为 WriteMeToTheLog (包含您提取的日志逻辑)也必须实现 LogWriter 因为它看起来像一个 实施。
    客户机类应该与 ,可能作为构造函数中的字段集,而它仍然可以实现 LogWritter 如果有道理的话。

    class WriteMeToTheLog implements LogWriter { ...}
    

    以及:

    public class OneOfMyClasses extends BaseClass implements LogWriter {
        private LogWriter logWriter;
    
        public OneOfMyClasses (LogWriter logWriter){
           this.logWriter = logWriter;
        }
    
        @Override
        public void writeLog(){
            Date rightNow = new Date();       
            logWriter.write();
        }
    }
    

    现在可以通过设置依赖项来实例化客户机类:

    OneOfMyClasses o = new OneOfMyClasses(new WriteMeToTheLog(new LogEntry(timestampSDF.format(rightNow), boolean01, someInt, boolean02).toString().getBytes());