Java: почему объявление недостаточно в интерфейсе? - PullRequest
1 голос
/ 01 мая 2010

Большой класс содержит Format-interfcase и Format-class. Формат-класс содержит методы, а интерфейс имеет значения полей. Я мог бы иметь поля в классе Format, но цель с интерфейсом. Так я просто создаю пустышки, чтобы устранить ошибки, проблемы дизайна или что-то еще?

КЛЮЧ: Декларация VS Инициализация

  1. Объясните терминами, почему вы должны инициировать в интерфейсе.
  2. Какая логика стоит за этим?
  3. К каким проблемам это приводит к использованию интерфейса?

Пример кода с проблемой init-interface

import java.util.*;
import java.io.*;

public class FormatBig
{

        private static class Format implements Format
        {
                private static long getSize(File f){return f.length();}
                private static long getTime(File f){return f.lastModified();}
                private static boolean isFile(File f){if(f.isFile()){return true;}}
                private static boolean isBinary(File f){return Match.isBinary(f);}
                private static char getType(File f){return Match.getTypes(f);}
                private static String getPath(File f){return getNoErrPath(f);}
                //Java API: isHidden, --- SYSTEM DEPENDED: toURI, toURL


                Format(File f)
                {
                  // PUZZLE 0: would Stack<Object> be easier?
                        size=getSize(f);
                        time=getTime(f);
                        isfile=isFile(f);
                        isBinary=isBinary(f);
                        type=getType(f);
                        path=getPath(f);

                    //PUZZLE 1: how can simplify the assignment?
                        values.push(size);
                        values.push(time);
                        values.push(isfile);
                        values.push(isBinary);
                        values.push(type);
                        values.push(path);
                }
        }

        public static String getNoErrPath(File f)
        {
                try{return f.getCanonicalPath();
                }catch(Exception e){e.printStackTrace();}
        }

        public static final interface Format
        {
                //ERR: IT REQUIRES "="
                public long size;
                public long time;
                public boolean isFile=true;   //ERROR goes away if I initialise wit DUMMY
                public boolean isBinary;
                public char type;
                public String path;
                Stack<Object> values=new Stack<Object>();
        }

        public static void main(String[] args)
        {
                Format fm=new Format(new File("."));
                for(Object o:values){System.out.println(o);}
        }
}

Ответы [ 2 ]

6 голосов
/ 01 мая 2010

Поля в интерфейсах неявно public final static.

static будет означать, что они не зависят от экземпляров. Это, вероятно, не то, что вы хотите.

final означает, что они должны быть назначены ровно один раз во время инициализации класса, так как поля также static. Обычно это означает присвоение в объявлении, но может использовать статический инициализатор. Если бы они были полями экземпляра (не static), их нужно было бы назначить либо в объявлении, либо в конструкторах (которые неявно или явно вызывают super вместо конструктора "this"), либо в экземпляре инициализатора.

Возможно, вам следует переместить поля экземпляра в реализующий класс и пометить их final.

3 голосов
/ 01 мая 2010

@ Том ответил на ваш прямой вопрос.По сути, вы не можете объявлять атрибуты уровня экземпляра (или переменные уровня класса) в интерфейсе.Атрибуты уровня экземпляра должны быть объявлены в классе.

Если вы хотите, чтобы несколько классов совместно использовали одни и те же объявления атрибутов, вы могли бы поместить их в абстрактный суперкласс.Но лучше всего объявлять атрибуты как private и получать к ним доступ через геттеры и сеттеры.

Есть несколько других проблем с вашим кодом:

  • Выне может объявить класс и интерфейс с одинаковым именем в одном и том же пространстве имен.У вас есть класс с именем Format, который реализует интерфейс с именем Format, оба из которых объявлены в пространстве имен FormatBig.И даже если бы вы могли (например, потому что они были объявлены в разных пространствах имен), это плохая практика.Дайте классу и интерфейсу разные имена.

  • Вы должны использовать вложенные классы экономно.Мне кажется, что для удобства вы могли бы встроить класс и интерфейс Format в FormatBig, так что вам придется редактировать и компилировать только один файл.Это лениво.Кроме того, если вы делаете это для организации своего кода, узнайте, как использовать пакеты Java.

...