2012-07-04 7 views
12

Я следующий сценарий:Java: Использование метода родительского класса для доступа дочернего класса переменной

public class A { 

    private int x = 5; 

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


public class B extends A { 

    private int x = 10; 

    /*public void print() 
    { 
     System.out.println(x);  
    }*/ 

    public static void main(String[] args) { 
     B b = new B(); 
     b.print(); 
    } 

} 

На выполнение кода, выход: 5.

Как получить доступ к классу ребенка (Б) переменная (x) через метод родительского класса?

Может ли это быть сделано без переопределения метода print() (т. Е. Раскомментирование его в B)?

[Это важно, потому что на переопределение придется переписывать весь код для печати() метод снова]

EDITED

Больше Разъяснение: -

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

(Спасибо всем за ваше время и помощь)

+0

Если вы хотите напечатать переменную B '' ', вы намерены, чтобы' x' отличались от '' '' 'или они должны быть одинаковыми? –

+0

@WeiHao из кода очевидно, что 'x' в' A' должно быть 5, то в 'B' должно быть 10. Он хочет' B.print() 'выводить 10, потому что он не доволен с выходом 5. Таким образом, он ожидает, что они будут разными. –

+0

@Jayant Это не о родителе, у которого нет информации, это не так. проблема в том, что значение 'x' не переопределяется при создании' B'. –

ответ

8
class A { 
    private int x = 5; 

    protected int getX() { 
     return x; 
    } 

    protected void setX(int x) { 
     this.x = x; 
    } 

    public void print() { 
     // getX() is used such that 
     // subclass overriding getX() can be reflected in print(); 
     System.out.println(getX()); 
    } 
} 

class B extends A { 
    public B() { 
     // setX(10); // perhaps set the X to 10 in constructor or in main 
    } 

    public static void main(String[] args) { 
     B b = new B(); 
     b.setX(10); 
     b.print(); 
    } 
} 

EDITED

Ниже приведен общий ответ, используя абстрактный класс и метод решения подобного сценария:

abstract class SuperA { 
    protected abstract Object getObj(); 

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

class A extends SuperA { 
    @Override 
    protected Object getObj() { 
     // Your implementation 
     return null; // return what you want 
    } 
} 

class B extends A { 
    @Override 
    protected Object getObj() { 
     // Your implementation 
     return null; // return what you want 
    } 

    public static void main(String[] args) { 
     B b = new B(); 
     b.print(); 
    } 
} 
+0

Приятное универсальное решение. Это довольно OOP = D. Кроме того, очень похоже на C#. –

+0

@Shingetsu, спасибо, но я ничего не знаю о C#, я планирую изучить его, но моя работа не позволяет ... –

+0

в основном, C# - это просто элегантная версия Java. Если вы хорошо знаете Java, у вас не будет особых проблем с ее изучением, хотя знание .NET и C++ пригодится = D. –

0

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

Как так:

public class A { 

    private int x = 5; 

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

    protected void setX(int x) 
    { 
     this.x = x; 
    } 

    protected int getX() 
    { 
     return x; 
    } 

} 


public class B extends A { 

    /*public void print() 
    { 
     System.out.println(x);  
    }*/ 

    public B() 
    { 
     setX(10); 
    } 

    public static void main(String[] args) { 
     B b = new B(); 
     b.print(); 
    } 

} 
+0

Это тоже работает, хотя, если x нужно изменить в какой-то момент? Это ограничивается приведенным примером. –

+0

Сделайте сеттер X также тогда. –

+0

@VictorWong Это не настоящий геттер, переменная на самом деле отсутствует. –

0

Вы всегда можете добавить его в конструктор:

public class B extends A { 

    //this line is unnecessary: private int x = 10; 

    /*public void print() 
    { 
     System.out.println(x);  
    }*/ 

    public B() 
    { 
     x=10; 
    } 


    public static void main(String[] args) { 
     B b = new B(); 
     b.print(); 
    } 

} 

Причина это не будет работать, как вы пытаетесь это то, что значения по умолчанию только один раз получить оценку. Так что, когда он по умолчанию 5 в A, он остается 5, даже если вы использовали по умолчанию 10 в B.

+0

Во-первых, изменение x в конструкторе B не будет работать, если видимость x является частной. Во-вторых, даже если мы сделаем видимость x для защиты, она изменит значение переменной x в родительском классе. Требуется не изменять значение переменной в родительском классе, а использовать значение переменной дочернего класса. – Jayant

+0

@Jayant переменная класса ребенка *** НЕ СУЩЕСТВУЕТ ***. Вы делаете переменную в родительском, даете ей значение по умолчанию. Значения по умолчанию оцениваются один раз. Вы даете *** SAME VARIABLE *** другое значение по умолчанию в 'B', но значение по умолчанию уже было оценено в' A'. Когда вы делаете 'B', IL 1st оценивает значение по умолчанию для' x' в 'A', затем' x' в 'B', но так как' x' уже получил оценку в 'A', строка' private int x = 10; 'абсолютно ничего. –

+0

Я не понимаю, что вы пытаетесь сказать. Очевидно, что оператор private int x = 10 в классе B выделяет некоторую новую память для переменной x в классе B и полностью независим от переменной x в A. – Jayant

6

После прочтения всех ответов, размещенных здесь, я получил то, что искал. Следующее, что я чувствую это лучший ответ на мой вопрос:

public class A { 
    private int x = 5;  
    protected int getX(){ 
     return x; 
    }  
    public void print(){ 
     System.out.println(getX()); 
    } 
} 
public class B extends A { 
    private int x = 10; 
    protected int getX(){ 
     return x; 
    } 
    public static void main(String[] args) { 
     B b = new B(); 
     b.print(); 
    } 
} 

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

+0

Вы должны были на самом деле выбрать ответ @VictorWong как лучший ответ ... – kakacii

+0

@kakacii Да, хотя ответ VictorWong не отвечает точно, люди считают его более полезным. Я изменил свой выбор. Спасибо :) – Jayant

+0

@Jayant Я не вижу никакой разницы между моим общим решением (а не первым, но отредактированным) и вашим ответом здесь, кроме того, что вы заменяете 'obj'' x'. Не обижайтесь, но я хочу знать, почему мое решение недостаточно точное. –

1

Для решения вашего вопроса вы должны определить поля родительского класса A, подобные защищенным (поэтому он будет унаследован от дочернего класса) и установить значение поля x внутри конструктора в дочернем классе B. Метод печати также наследуется от класса A, поэтому вы можете ссылаться на него непосредственно из родительского класса.

Я надеюсь, что это может вам помочь.

public class A 
{ 
    // fields declaration 
    protected int x = 5; 

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



public class B extends A 
{ 

    public B() 
    { 
     // set child x value. The field have been defined in the parent class 
     x = 10; 
    } 

    public static void main(String[] args) 
    { 
     A a = new A(); 
     a.print(); // print 5 

     B b = new B(); 
     b.print(); // print 10 
    } 

} 
Смежные вопросы