Java: родительские методы доступа к статическим переменным подклассов? - PullRequest
2 голосов
/ 22 марта 2011

Я пытаюсь понять, как обходить полиморфизм в Java. Я создал родительский класс, который имеет слишком много общих методов, которые все дети будут использовать одинаково.
Каждый из дочерних классов подклассов имеет общую статическую информацию. Эти переменные или информация будут использоваться в методах, объявленных только в родительском элементе.
Проблема в том, что доступ к статическим переменным из родительских методов не представляется возможным,
Это решение объявлять общую информацию для каждого экземпляра, но поскольку будет тысячи экземпляров, это такая пустая трата памяти.
Простая проработка того, что я имею в виду, это следующий код:

    class testParent {
    static int k;
    public void print()
    {
      System.out.println(k);    
    }
   }

   class testChild2 extends testParent 
   {

    static
    {
        testChild2.k =2;
    }
   }

   public class testChild1 extends testParent{
    static
    {
        testChild1.k = 1;
    }

    public static void main(String[] args)
    {

        new testChild1().print();
        new testChild2().print();

        new testChild1().print();
    }
 }

ожидаемый результат был
1
2 * * +1010 1.
но что происходит, это:
1
2
2
Можно подумать, что при инициации каждого подкласса устанавливаются статические переменные этого подкласса, и тогда все методы, относящиеся к этому подклассу, имеют доступ к соответствующему значению 'k'.
Но на самом деле происходит то, что все подклассы редактируют одну и ту же статическую переменную, которая является общей для всех подклассов, и, следовательно, разрушают весь мой смысл использования статических переменных для каждого подкласса и его экземпляров и использования общих методов в Parent, обращающихся к этим переменным.



Есть идеи, как это можно сделать?

Ответы [ 4 ]

4 голосов
/ 22 марта 2011

Можно получить доступ к статическим данным подклассов с помощью абстрактного (нестатического) метода:

abstract public class Parent {
   protected abstract int getK();

   public void print() {
      System.out.println(getK());
   }
} 

public class Child1 extends Parent {
   private static final int CHILD1_K = 1;

   protected int getK() { return CHILD1_K; }
}

public class Child2 extends Parent {
   private static final int CHILD2_K = 2;

   protected int getK() { return CHILD2_K; }
}
1 голос
/ 22 марта 2011

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

Решение: не делать k статичным.

class testParent {
    int k;
    public void print()
    {
        System.out.println(k);    
    }
}

class testChild2 extends testParent 
{
    {
        this.k =2;
    }
}

class testChild1 extends testParent{
    {
        this.k = 1;
    }

    public static void main(String[] args){
        new testChild1().print();
        new testChild2().print();
        new testChild1().print();
    }
}

Демо
(игнорируйте бизнес static class - это просто для того, чтобы он работал в ideone).

1 голос
/ 22 марта 2011

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

1 голос
/ 22 марта 2011

При создании нового testChild2 (). Print ();статический блок на testChield2 был выполнен и измените значение на 2.

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

Этот вывод дает желаемый результат:

 class testParent {
    static int k;
    public void print()
    {
      System.out.println(k);    
    }
   }

   class testChild2 extends testParent 
   {

    {
        testChild2.k =2;
    }
   }

   public class testChild1 extends testParent{
    {
        testChild1.k = 1;
    }

    public static void main(String[] args)
    {

        new testChild1().print();
        new testChild2().print();

        new testChild1().print();
    }
 }

Нестатические блоки кода выполняются каждый раз, когда создается экземпляр класса.

...