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

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

Это вопрос, который меня задали в интервью: у меня есть класс A с частными членами, а класс B продолжит A. Я знаю, что к закрытым членам класса нельзя обращаться, но возникает вопрос: мне нужно получить доступ к закрытым членам класс A из класса B, а не создавать переменные с тем же значением в классе B.

4b9b3361

Ответ 1

Интервьюер либо тестировал ваши знания о модификаторах доступа, либо ваш подход к изменению существующих классов, либо и то, и другое.

Я бы перечислил их (публичный, закрытый, защищенный, закрытый) с объяснением каждого. Затем продолжил говорить, что класс A необходимо будет изменить, чтобы разрешить доступ к этим членам из класса B, либо путем добавления сеттеров и геттеров, либо путем изменения модификаторов доступа членов. Или класс B может использовать отражение. Наконец, расскажите о плюсах и минусах каждого подхода.

Ответ 2

Отражение? Опуская импорт, это должно работать:

public class A {

    private int ii = 23;

}

public class B extends A {

    private void readPrivateSuperClassField() throws Exception {
        Class<?> clazz = getClass().getSuperclass();
        Field field = clazz.getDeclaredField("ii");
        field.setAccessible(true);
        System.out.println(field.getInt(this));
    }

    public static void main(String[] args) throws Exception {
        new B().readPrivateSuperClassField();
    }

}

Это не сработает, если вы сделаете что-то подобное перед вызовом readPrivateSuperClassField();:

System.setSecurityManager(new SecurityManager() {
        @Override
        public void checkMemberAccess(Class<?> clazz, int which) {
            if (clazz.equals(A.class)) {
                throw new SecurityException();
            } else {
                super.checkMemberAccess(clazz, which);    
            }
        }
    });

И есть другие условия, при которых подход Reflection не будет работать. См. документы API для SecurityManager и AccessibleObject для получения дополнительной информации. Информация. Спасибо CPerkins за указание на это.

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

Ответ 3

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

Вы можете использовать хаки, аксессоры, рекламировать участника или #define private public (хех). Но это все краткосрочные решения - вам, вероятно, придется пересмотреть разбитую архитектуру на определенном этапе.

Ответ 4

Используя публичных аксессоров (геттеров и сеттеров) членов A-рядовых членов...

Ответ 5

Вы не можете получить доступ к закрытым членам из родительского класса. Вы защищаете его или имеете защищенный/общедоступный метод, который имеет к ним доступ.

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

Ответ 6

Вложенный класс может получить доступ ко всем частным членам его окружающего класса - как к полям, так и к методам. Следовательно, открытый или защищенный вложенный класс, унаследованный подклассом, имеет косвенный доступ ко всем частным членам суперкласса.

public class SuperClass
{
    private int a = 10;
    public void makeInner()
    {
        SubClass in = new SubClass();
        in.inner();
    }
    class SubClass
    {
        public void inner()
        {
            System.out.println("Super a is " + a);
        }
    }
    public static void main(String[] args)
    {
        SuperClass.SubClass s = new SuperClass().new SubClass();
        s.inner();
    }
}

Ответ 7

Если я правильно понимаю вопрос, вы можете изменить private на protected. Защищенные переменные доступны для подклассов, но в противном случае ведут себя как частные переменные.

Ответ 8

Используя сеттеры и геттеры, вы можете получить к нему доступ.

Ответ 9

Из JLS & sect; 8.3. Декларации полей:

Частное поле суперкласса может быть доступно для подкласса - например, если оба класса являются членами одного и того же класса. Тем не менее частное поле никогда не наследуется подклассом.

Я пишу код примера:

public class Outer
{
    class InnerA
    {
        private String text;
    }
    class InnerB extends InnerA
    {
        public void setText(String text)
        {
            InnerA innerA = this;
            innerA.text = text;
        }
        public String getText()
        {
            return ((InnerA) this).text;
        }
    }
    public static void main(String[] args)
    {
        final InnerB innerB = new Outer().new InnerB();
        innerB.setText("hello world");
        System.out.println(innerB.getText());
    }
}

Объяснение доступности InnerA.text здесь JLS & sect; 6.6.1. Определение доступности:

В противном случае член или конструктор объявляется закрытым, а доступ разрешен только тогда, когда он встречается внутри тела класса верхнего уровня (§7.6), который включает объявление члена или конструктора.

Ответ 10

Вы можете использовать сеттеры и getters класса A. Что дает такое же ощущение, как если вы используете объект класса A.

Ответ 11

Думали ли вы о том, чтобы сделать их защищенными? Просто, чтобы быть уверенным, что вы знаете об этом варианте, если вы тогда прощаете меня за то, что вы поднимаете эту мелочи;)

Ответ 12

  • Доступ к частным членам не может выполняться в производном классе
  • Если вы хотите получить доступ, вы можете использовать методы getter и setter.
class A
{
 private int a;
 void setA(int a)
 {
    this.a=a;
 }
 int getA()
 {
   return a;
 }
}

Class B extends A
{
 public static void main(String[] arg)
  {
     B obj= new B();
     obj.setA(10);
     System.out.println("The value of A is:"+obj.getA());
  } 
}

Ответ 13

Частный будет скрыт, пока вам не будет предоставлен правильный доступ к нему. Например, Getters или сеттеры программистом, который написал родителя. Если они не видны этим, то либо принять тот факт, что они просто закрыты и недоступны для вас. Почему именно вы хотите это сделать?

Ответ 14

Я не знаю о Java, но на некоторых языках вложенные типы могут делать это:

    class A {
        private string someField;
        class B : A {
            void Foo() {
                someField = "abc";
            }
        }
    }

В противном случае используйте метод доступа или поле protected (хотя их часто злоупотребляют).

Ответ 15

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

Ответ 16

Очевидно, что их защита или добавление сеттеров/геттеров является предпочтительным методом. Отражение - это вариант отчаяния.

Просто чтобы показать интервьюеру, ЕСЛИ "доступ" означает доступ на чтение, а IF Class A генерирует XML или JSON и т.д., вы можете сериализовать A и проанализировать интересные поля.

Ответ 17

    Class A
{
  private int i;

  int getValue()
    {
      return i;
  }
}
class B extends A
{
   void getvalue2()
    {
      A a1= new A();
      sop(a1.getValue());
    }
}

Ответ 18

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

Ответ 19

Вы не можете напрямую обращаться к каким-либо отдельным переменным класса извне.

Вы можете получить доступ к частному члену, используя getter и setter.

Ответ 20

Способы доступа к закрытым членам суперкласса в подклассе:

  • Если вы хотите получить доступ к пакету, просто измените приватные поля на защищенные. Он позволяет получить доступ к тому же пакетному подклассу.
  • Если у вас есть частные поля, просто укажите некоторые методы доступа (getters), и вы можете получить к ним доступ в своем подклассе.
  • Вы также можете использовать внутренний класс, например

    public class PrivateInnerClassAccess {
    private int value=20;
    
    class InnerClass {
    
    public void accessPrivateFields() {
        System.out.println("Value of private field : " + value);
    }
    
    }
    
    public static void main(String arr[])
    {
        PrivateInnerClassAccess access = new PrivateInnerClassAccess();
        PrivateInnerClassAccess.InnerClass innerClass = access.new InnerClass();
        innerClass.accessPrivateFields();
    
    }
    
    }
    

    4. Вы также можете использовать Reflection, например,

     public class A {
    private int value;
    public A(int value)
    {
        this.value = value;
    }
    }
    
    public class B {
    public void accessPrivateA()throws Exception
    {
        A a = new A(10);
        Field privateFields = A.class.getDeclaredField("value");
        privateFields.setAccessible(true);
        Integer value = (Integer)privateFields.get(a);
        System.out.println("Value of private field is :"+value);
    }
    
    
    public static void main(String arr[]) throws Exception
    {
        B b = new B();
        b.accessPrivateA();
    }
    }
    

Ответ 21

Непосредственно мы не можем получить к нему доступ. но с помощью Setter и Getter мы можем получить доступ,

Код:

class AccessPrivate1 {    

    private int a=10; //private integer    
    private int b=15;    
    int getValueofA()    
    {    
        return this.a;    

    }    

    int getValueofB()    
    {    
        return this.b;    
    }    
}    


public class AccessPrivate{    
    public static void main(String args[])    
    {    
        AccessPrivate1 obj=new AccessPrivate1();    

        System.out.println(obj.getValueofA()); //getting the value of private integer of class AccessPrivate1    

        System.out.println(obj.getValueofB()); //getting the value of private integer of class AccessPrivate1    
    }    
}    

Ответ 22

В коде можно использовать Аксессоры (метод getter и setter).

Ответ 23

Используя метод setter, вы можете использовать else с помощью refection, вы можете использовать частный член класса, установив, что участник говорит a - взять из класса и установите a.setAccessible(true);

Ответ 24

Вы можете изменить его на защищенный. Пожалуйста, обратитесь к этому

https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html

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

private void getPropertiesFromPrivateClass(){

    Field[] privateVariablesArray = PrivateClassName.getClass().getDeclaredFields();
    Set<String> propertySet = new HashSet<String>();
    Object propertyValue;
    if(privateVariablesArray.length >0){
        for(Field propertyVariable :privateVariablesArray){
            try {

                if (propertyVariable.getType() == String.class){
                    propertyVariable.setAccessible(true);
                    propertyValue = propertyVariable.get(envtHelper);
                    System.out.println("propertyValue");
                }
            } catch (IllegalArgumentException illegalArgumentException) {
                illegalArgumentException.printStackTrace();

            } catch (IllegalAccessException illegalAccessException) {
                illegalAccessException.printStackTrace();

            }
        }

Надеюсь, что это поможет. Happy Learning:)

Ответ 25

Ниже приведен пример доступа к закрытым членам суперкласса в объекте подкласса.

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

Ниже представлен суперкласс Fruit

public class Fruit {
    private String type;

    public Fruit() {
    }

    public Fruit(String type) {
        super();
        this.type = type;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

}

Ниже представлен подкласс Guava, который наследуется от Fruit

public class Guava extends Fruit{
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Guava(String name,String type) {
        super(type);
        this.name=name;
    }
}

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

public class Main {

    public static void main(String[] args) {

        Guava G1=new Guava("kanpuria", "red");
        System.out.println(G1.getName()+" "+G1.getType());

    }

}

Ответ 26

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

Ответ 27

Простой!!!

public class A{
private String a;
private String b;
//getter and setter are here
}

public class B extends A{
public B(String a, String b){ //constructor
super(a,b)//from here you got access with private variable of class A
}
}

спасибо

Ответ 28

Модификаторы - это ключевые слова, которые вы добавляете к этим определениям для изменения их значений. Язык Java имеет множество модификаторов, в том числе:

  • Модификаторы доступа Java
  • Модификаторы недоступности

Чтобы использовать модификатор, вы включаете его ключевое слово в определение класса, метода или переменной. Модификатор предшествует остальной части инструкции.

Здесь больше информации:

http://tutorialcorejava.blogspot.in/p/java-modifier-types.html