Подтвердить что ты не робот

Абстрактные переменные в Java?

Я из С#, где это было легко и возможно.

У меня есть этот код:

public abstract class clsAbstractTable {

    public abstract String TAG;
    public abstract void init();

}

но Eclipse говорит мне, что я использую незаконный модификатор.

У меня есть этот класс:

public class clsContactGroups extends clsAbstractTable {


}

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

Как мне определить свой абстрактный класс, чтобы мне было предложено реализовать тезисы?

РЕДАКТИРОВАТЬ 1

Я создам разные классы для разных таблиц db. Каждый класс должен иметь собственную переменную TABLENAME, без исключения. Я должен убедиться, что эта переменная является статической каждый раз, когда я создаю новый класс, который расширяет абстрактный класс.

Тогда в абстрактном классе у меня будет метод, например: init();

Если в этом методе init() я вызываю TABLENAME, он должен взять значение из подкласса.

что-то подобное должно также работать

String tablename=(clsAbstract)objItem.TABLENAME;
// where objItem can be any class that extended clsAbstract;

РЕДАКТИРОВАТЬ 2

Я хочу константу (статическую), определенную в каждом классе, имеющую имя, определенное в абстрактном выражении.

  • Я определяю переменную TABLENAME в абстрактном виде, но значения не задано.
  • Я создаю clsContactGroups, мне должно быть предложено реализовать TABLENAME, вот где получаются некоторые данные. например: TABLENAME = "контактные группы";
  • Я создаю clsContacts второго класса, мне должно быть предложено реализовать TABLENAME, здесь есть некоторые данные. например: TABLENAME = "контакты"; и т.д...
4b9b3361

Ответ 1

Я думаю, ваше замешательство связано с свойствами С# против полей/переменных. В С# вы не можете определять абстрактные поля, даже в абстрактном классе. Тем не менее, вы можете определить абстрактные свойства, поскольку это эффективные методы (например, скомпилированы в get_TAG() и set_TAG(...)).

Как напомнили некоторые, у вас никогда не должно быть открытых полей/переменных в ваших классах, даже в С#. Несколько ответов намекнули на то, что я рекомендовал бы, но не дал понять. Вы должны перевести идею на Java как свойство JavaBean, используя getTAG(). Тогда ваши подклассы должны будут реализовать это (я также написал проект с табличными классами, которые это делают).

Итак, вы можете иметь абстрактный класс, определенный таким образом...

public abstract class AbstractTable {

    public abstract String getTag();
    public abstract void init();

    ...
}

Затем в любых конкретных подклассах вам нужно будет определить статическую конечную переменную (константу) и вернуть ее из getTag(), примерно так:

public class SalesTable extends AbstractTable {

    private static final String TABLE_NAME = "Sales";

    public String getTag() {
        return TABLE_NAME;
    }

    public void init() {
        ...
        String tableName = getTag();
        ...
    }

}

EDIT:

Вы не можете переопределять унаследованные поля (на С# или Java). Вы также не можете переопределять статические члены, независимо от того, являются ли они полями или методами. Так что это также лучшее решение для этого. Я изменил пример метода init выше, чтобы показать, как это будет использоваться. Еще раз подумайте о методе getXXX в качестве свойства.

Ответ 2

Определите конструктор в абстрактном классе, который задает поле так, чтобы конкретные реализации соответствовали спецификации, требуемой для вызова/переопределения конструктора.

например.

public abstract class AbstractTable {
    protected String name;

    public AbstractTable(String name) {
        this.name = name;
    }
}

Когда вы расширяете AbstractTable, класс не будет компилироваться до тех пор, пока вы не добавите конструктор, который вызывает super("somename").

public class ConcreteTable extends AbstractTable {
    private static final String NAME = "concreteTable";

    public ConcreteTable() {
        super(NAME);
    }
}

Таким образом, разработчикам необходимо установить name. Таким образом, вы также можете делать (null) проверки в конструкторе абстрактного класса, чтобы сделать его более надежным. Например:

public AbstractTable(String name) {
    if (name == null) throw new NullPointerException("Name may not be null");
    this.name = name;
}

Ответ 3

В Java (или С++) нет таких объектов, как абстрактные переменные.

Если родительский класс имеет переменную, а дочерний класс расширяет родительский элемент, то дочерний элемент не должен реализовывать переменную. Ему просто нужен доступ к родительскому экземпляру. Либо получить/установить, либо защищенный доступ сделает.

"... поэтому мне должно быть предложено реализовать тезисы"? Если вы расширите абстрактный класс и не сможете реализовать абстрактный метод, компилятор скажет вам либо реализовать его, либо пометить подкласс как абстрактный. Это все подсказки, которые вы получите.

Ответ 4

Просто добавьте этот метод в базовый класс

public abstract class clsAbstractTable {

    public abstract String getTAG();
    public abstract void init();

}

Теперь каждый класс, который расширяет базовый класс (и не хочет быть абстрактным), должен предоставить TAG

Вы также можете пойти с ответом BalusC

Ответ 5

Лучшее, что вы могли бы сделать, это иметь accessor/mutators для переменной.
Что-то вроде getTAG()
 Таким образом, все реализующие классы должны были бы реализовать их.

Абстрактные классы используются для определения абстрактного поведения, а не данных.

Ответ 6

Поскольку реализации переменной не существует, она не может быть абстрактной;)

Ответ 7

Почему вы хотите, чтобы все подклассы определяли переменную? Если каждый подкласс должен иметь его, просто определите его в суперклассе. Кстати, учитывая, что хорошая практика ООП не выставлять поля в любом случае, ваш вопрос имеет еще меньший смысл.

Ответ 8

Измените код на:

public abstract class clsAbstractTable {
  protected String TAG;
  public abstract void init();
}

public class clsContactGroups extends clsAbstractTable {
  public String doSomething() {
    return TAG + "<something else>";
  }
}

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

Боковое примечание: не используйте CAPS в качестве имени переменной; общая мудрость заключается в том, что все идентификаторы шапок относятся к константам, то есть к неизменяемым фрагментам данных.

Ответ 9

Чтобы добавить метаданные для каждого класса, возможно, аннотация может быть правильным способом.

Однако вы не можете обеспечить наличие аннотации в интерфейсе, так же, как вы не можете принудительно использовать статические элементы или существование определенного конструктора.

Ответ 10

Существует два способа определения абстрактных свойств в java без выделения свойства как абстрактного.

1st way: Определите параметризованный конструктор в абстрактном классе, например:

public abstract class clsAbstractTable {
       private String TAG;
       public clsAbstractTable (String TAG) {
            this.TAG= TAG;
       }
}

При определении параметризованного конструктора в абстрактном классе подклассы вынуждены определять свои собственные конструкторы и вызывать супер-конструктор, следовательно, передавать свой собственный TAG.

Второй способ: определить свойство как метод getter, например:

public abstract class clsAbstractTable {
    public abstract String getTAG();
}

Таким образом, значение свойства TAG делегировано для каждого конкретного класса.

Источник: Определить абстрактное свойство в java

Ответ 11

Используйте enums для принудительного выравнивания значений:

enum Speed {
    HIGH, LOW;
}
private abstract  class SuperClass {
    Speed speed;
    SuperClass(Speed speed) {
        this.speed = speed;
    }
}
private class ChildClass extends SuperClass {
    ChildClass(Speed speed) {
        super(speed);
    }
}

Ответ 12

В моем эксперименте абстрактному классу Java нужно указывать ключевое слово abstract. И наоборот, будет выдана ошибка, что "здесь нельзя поместить абстрактный модификатор". Вы можете указать абстрактные атрибуты так же, как обычные атрибуты.

public abstract class Duck implements Quackable, Observable {
    // observerList should keep the list of observers watching this duck 
    List<Observer> observerList;

    public AttackBehavior attackBehavior;
    public FlyBehavior flyBehavior;

    public Duck() {
        observerList = new ArrayList<Observer>();
    }
}

А в подклассе вы можете напрямую использовать эти атрибуты this.flyBehavior или this.attackBehavior. Вам не нужно переписывать атрибуты в поле атрибутов.

Ответ 13

Нет, Java не поддерживает абстрактные переменные. Это также не имеет большого смысла.

Какое конкретное изменение "реализации" переменной вам ожидает подкласс?

Когда у меня есть переменная abstract String в базовом классе, что должен сделать подкласс для того, чтобы сделать ее не абстрактной?