Как получить доступ к значениям полей из базового класса?

Я хочу получить доступ к полям класса из базового класса в Java. Я могу сделать это в дотнете. см. пример:

public class a{

// here I want to read the value of name or f1 or f2 or every other field values from derived classes
}
public class b extends a{
  public string name;
}
public class c extends a{
  public string f1;
  public string f2;
}

Как это сделать?


person Community    schedule 02.10.2013    source источник
comment
Не делай этого. Суперкласс не должен знать атрибуты базовых классов. У тебя видимо конструктивный недостаток.   -  person Arnaud Denoyelle    schedule 02.10.2013
comment
Поток похож на воду, должен быть ------ > не таким, как <--------   -  person Suresh Atta    schedule 02.10.2013
comment
Краткий ответ: Вы не можете. Для лучшего ответа, пожалуйста, объясните, что вы пытаетесь сделать.   -  person Thilo    schedule 02.10.2013
comment
Если это можно сделать на C# (?), то это довольно страшно...   -  person Gyro Gearless    schedule 02.10.2013
comment
@Thilo Это фактически неверно. Это возможно (см. ответ Марко), но это также сводит на нет цель наличия подклассов.   -  person Torben    schedule 02.10.2013
comment
@Torben: Это был короткий ответ :-) (И поскольку ответ Марко включает в себя приведение типа к подклассу, доступ на самом деле осуществляет не родительский класс, это просто обычный общедоступный доступ, доступный где угодно - и вариант исчезнет, ​​если поле больше не является общедоступным).   -  person Thilo    schedule 02.10.2013
comment
Чувак, я раньше делал это в точечной сети. то, что я хочу сделать, это создать класс для создания методов базы данных, таких как вставка или выбор. Я хочу, чтобы высший класс знал поля из производного класса и подготовил для него правильную команду вставки. Я даже могу читать имена полей таким образом, но могу читать значения.   -  person    schedule 03.10.2013


Ответы (3)


Вы не можете прочитать поля, которыми не владеет ваш класс, без явного указания имени подкласса. Итак, это выполнимо следующим образом:

((c)this).f1;

Однако делать это было бы неприятным запахом кода: теперь вы привязываете абстракцию, воплощенную a, к одной из его конкретных реализаций/расширений. Вам лучше переосмыслить свой дизайн.

Важное замечание по соглашениям о коде

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

person Marko Topolnik    schedule 02.10.2013
comment
Не могу не подчеркнуть. Вам следует лучше переосмыслить свою часть дизайна. - person Torben; 02.10.2013

Вы действительно не хотите этого делать, поскольку это побеждает идею наследования.

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

Выполнение таких вещей, как (i) использование отражения и (ii) приведение к производным классам, является хаком, и его следует избегать. Причина в том, что изменение производного класса не должно вызывать необходимость изменений в базовом классе.

person Bathsheba    schedule 02.10.2013
comment
Я могу читать имена полей таким образом, но могу читать значения. - person ; 03.10.2013

Что вы должны сделать в этом случае, так это определить абстрактные методы в вашем классе a, которые должны быть реализованы классами b и c. Затем вы можете вызвать эти методы из a, чтобы получить значения, установленные b и c.

public abstract class a{

// here I want to read the value of name or f1 or f2 or every other field values from derived classes
    abstract String getName();
    abstract String getF1();
    abstract String getF2();
}

public class b extends a{
  private String name;

  @Override
  public String getName() { return name; } 

  @Override
  public String getF1() { return null; }

  @Override
  public String getF2() { return null; }
}

public class c extends a{
  public String f1;
  public String f2;


  @Override
  public String getName() { return null; } 

  @Override
  public String getF1() { return f1; }

  @Override
  public String getF2() { return f2; }
}
person Jaran    schedule 02.10.2013
comment
Это тоже не лучшее решение. Теперь все подклассы должны знать обо всех полях других подклассов. - person Thilo; 02.10.2013
comment
@Thilo Верно, но, учитывая первоначальный пример кода OP, я не думаю, что мы сможем этого избежать. Наличие суперкласса с двумя, казалось бы, разными и не связанными между собой подклассами — не очень хорошая идея. Нам нужно больше знать о том, чего хочет достичь OP. - person Torben; 02.10.2013
comment
Да, нам нужно знать, что на самом деле хочет сделать OP. - person Thilo; 02.10.2013
comment
Учитывая исходный запрос ОП, я считаю это наиболее простым и понятным решением. Тем не менее, я полностью согласен с тем, что это не очень хорошее решение, и первоначальный дизайн OP, возможно, следует пересмотреть. - person Jaran; 02.10.2013
comment
Чувак, я раньше делал это в точечной сети. то, что я хочу сделать, это создать класс для создания методов базы данных, таких как вставка или выбор. Я хочу, чтобы высший класс знал поля из производного класса и подготовил для него правильную команду вставки. Я даже могу читать имена полей таким образом, но могу читать значения. - person ; 03.10.2013
comment
@EhsanShirzadi Мне кажется, наследование - это не то, что вам здесь нужно. Что вам нужно сделать, так это создать отдельный класс для ваших операторов вставки и создания (либо класс, который просто генерирует запросы, либо тот, который их выполняет), и его метод должен принимать объекты вашего домена в качестве параметров. - person Jaran; 03.10.2013