How do I get the attributes of Class A, a parent class (super class), to use it in Class C in Java.
For instance:
Class B extends A
Class C extends B
You need to declare the member protected:
public class A
{
protected int myInt = 5;
}
public class B extends A
{
}
public class C extends B
{
public int GetInt()
{
return myInt;
}
}
private member can be accessed only by the class itself, protected by the class and all the derived classes.
Typically it is best to keep attributes private, and access them via accessor (getter) and mutator (setter) methods from any other class, including derived classes. If the variable must or should be accessed directly from subclasses, which occasionally is desirable but not usually, then nearly always declare it protected.
Related
Consider an interface and its implementation,
interface A {
int a;
default void add() {
a = a+10;
}
public void sub();
}
class X implements A {
public sub() {
a = a-5;
}
}
I have to use the variable a in sub() function of class X. How can I do?
All variables declared inside interface are implicitly public static final variables(constants).
From the Java interface design FAQ by Philip Shaw:
Interface variables are static because Java interfaces cannot be instantiated in their own right; the value of the variable must be assigned in a static context in which no instance exists. The final modifier ensures the value assigned to the interface variable is a true constant that cannot be re-assigned by program code.
Since interface doesn't have a direct object, the only way to access them is by using a class/interface and hence that is why if interface variable exists, it should be static otherwise it wont be accessible at all to outside world. Now since it is static, it can hold only one value and any classes that implements it can change it and hence it will be all mess.
Hence if at all there is an interface variable, it will be implicitly static, final and obviously public!!!
The field a in the interface A always final and static and it isn't supposed to be modified in any way including reassigning it in an instance method.
Interfaces don't have the state. Abstract classes may.
abstract class A {
protected int a;
public void add() {
a += 10;
}
public abstract void sub();
}
final class X extends A {
public void sub() {
a -= 5;
}
}
I would use an abstract class instead of an interface. That way the variable can be modified by the extending class.
abstract class A{
int a=10;
void add(){
a=a+10;
}
public abstract void sub();
}
class X extends A{
public void sub(){
a=a-5;
}
}
Yes, We can use abstract class.
Since in interface variables declared are by default final.
Code with Interface
Code with Abstract Class
In Java, inner classes can normally access outer classes' private members.
While writing an Android app, I had a static inner class which extended it's outer class.
Turns out, private fields of the outer class could not be accessed:
class Outer {
private int m_field = 1;
static class Inner extends Outer {
Inner() {
m_field = 2;
}
}
}
It gives a confusing error message:
error: non-static variable m_field cannot be referenced from a static context
Even though nothing is static except the class itself.
When the field m_field is made protected, it compiles without a problem.
But also, when doing this:
class Outer {
private int m_field = 1;
static class Inner extends Outer {
Inner() {
((Outer)this).m_field = 2;
}
}
}
It works without problems.
Is this a bug in the compiler? Why would you need to cast to the outer class, which you are already an instance of?
EDIT:
For a real use-case of this, consider a class like this:
public abstract class MyItem {
private int m_counter = 0;
public abstract int updateSomething();
public static class CountItem extends MyItem {
public int updateSomething() { m_counter++; }
}
public static class DoubleCountItem extends MyItem {
public int updateSomething() { m_counter += 2; }
}
}
Pretty abstract example, but it can be used to provide basic implementations for abstract classes which don't need a lot of code on their own.
EDIT2:
As #Nathan suggests, it seems like this problem can be recreated by 2 classes without nesting:
class Base {
private int x = 0;
void a(Extended b) {
((Base)b).x = 1; //<-- with cast: compiles, without: error
}
}
class Extended extends Base {
}
Which gives better error message:
error: x has private access in Base
What you are seeing here is that, as long as you're within the class definition of Outer, you have access to private members of anything that has the class Outer, including things that are cast to Outer. They have to have the same class (as opposed to being instances of the class, with a different concrete subclass).
The inner class thing is a complication, here's a smaller example:
public class A {
private int foo = 0;
public String toString() {
return "A: foo=" + foo;
}
public static void main(String[] args) {
B b = new B();
System.out.println(b);
((A)b).foo = 1;
System.out.println(b);
}
}
class B extends A {
}
This compiles, only because it's within the class definition of A. Move the main method somewhere else (to within B, for instance), and you can no longer reference foo.
This is something that you see when coding equals methods, where you can access private fields of another instance of the same class because you're writing a method that's part of the class definition.
The Java language specification, in 6.6.1 Determining Accessibility:
Otherwise, if the member or constructor is declared private, then access is permitted if and only if it occurs within the body of the top level class (ยง7.6) that encloses the declaration of the member or constructor.
Without the cast to Outer access is not permitted because a) m_field is a private member of Outer, so it's not visible to subclasses, and b) it's not a member of the class being declared. Adding the cast means the compiler treats it as an Outer, and m_field becomes accessible.
I have a base class and subclass. Base class has common methods and its implementation which I want to use in subclass but I want to use subclass member variable instead of superclass. I do not want to rewrite the same method in subclass. Is there a way in Java to achieve this.
You could create a protected setter on the member variable & then override the value of the super's variable within the constructor of the subclass:
class Animal {
private String voice = "Oooo";
protected void setVoice(String voice) {
this.voice = voice;
}
public void speak() {
System.out.println(this.voice);
}
}
class Dog extends Animal {
public Dog() {
setVoice("woof");
}
}
You can use a method to access the member and override it in subclasses.
Class A{
public void DoStuff(){
int aux = getResource;
/*cool things with aux*/
}
protected int getResource(){
return internal_member;
}
private int internal_member;
}
Class B extends A{
private int another_member;
#Override
public int getResource(){
return another_member;
}
}
But take into account that this will not prevent people chaging class A from using the member directly, It might be better to create a base class for the members and the getters.
Another Option, as some people outlined before is to have the data member in the base class as protected and initialize it in the subclass:
Class A{
public void DoStuff(){
/*cool things with internal_member*/
}
protected List internal_member;
A(){internal_member = /*Set here a value*/}
}
Class B extends A{
B(){internal_member = /*Set a different value here! you can even declare a member and assign it here*/}
}
You can use constructors with arguments if you need.
Need to have more understanding about the private variables and inheritance. Earlier my understanding was if there is field in a class and when I'm inheriting the class, the fields that is not restricted by access(private variables) will be there in the inherited class. But I'm able use the private variables in base class if there is a public g/setter method.
How can I imagine a private variable in a base class.?
class A {
private int a;
public A(int a) { this.a = a; }
public int getA() {return a;}
}
class B extends A {
public B(int b) { super(b); }
public int getB() {return getA();}
}
int result = new B(10).getA();
result will be 10. Private field a in class A is kind of inherited to B but B can't access it directly. Only by using the public/default/protected accessor methods defined in class A. B is A so it always has all the same fields that are in A and possible some new fields defined in class B.
This is what Java tutorial http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html says:
A subclass does not inherit the private members of its parent class. However, if the superclass has public or protected methods for accessing its private fields, these can also be used by the subclass.
Nevertheless, see this
class A {
private int i;
}
class B extends A {
}
B b = new B();
Field f = A.class.getDeclaredField("i");
f.setAccessible(true);
int i = (int)f.get(b);
it works fine and returns value of field i from B instance. That is, B has i.
private variables / members are not inherited. That's the only answer.
Providing public accessor methods is the way encapsulation works. You make your data private and provide methods to get or set their values, so that the access can be controlled.
I have a abstract class where I want to declare final variables.
However, I want to assign the values to these variables only in the constructors of my sub-classes.
Apparently, this is not possible because all "final fields have to be initialized". I do not see why, since it is not possible anyway to instantiate an abstract class.
What I would like to have is something like this:
abstract class BaseClass {
protected final int a;
}
class SubClass extends BaseClass {
public SubClass() {
a = 6;
}
}
I imagine something similar to methods when you implement an interface. Then you are also forced to to implement the methods in the (sub-)class.
You should define a constructor in your abstract class that takes a value for a and call this constructor from your sub classes. This way, you would ensure that your final attribute is always initialized.
abstract class BaseClass {
protected final int a;
protected BaseClass(int a)
{
this.a = a;
}
}
class SubClass extends BaseClass {
public SubClass() {
super(6);
}
}