I was asked the following question:
Assuming all instance fields and all instance methods of class A in Java are private, which of the following are correct:
A is immutable
A is not for sure immutable because it could be that it extends a not-immutable class
A is not for sure immutable because you might be able to change its fields from static methods
I thought the correct answer was 1 but turns out 2 and 3 are both correct and 1 is not.
How come if everything is private you can still modify the fields?
Why if it extends a not immutable class, but still have everything private, it might be now immutable?
What does it mean to change its fields from static methods?
A could extend a class with fields that are public, in which case, those fields can be modified despite A itself not defining any mutable fields, as it will inherit fields and instance methods from its parent class.
Consider the following code:
class Child extends Parent {
private String name;
}
class Parent {
public int id;
}
class TestChild {
public static void main(final String[] args) {
final Child child = new Child();
//String s = child.name;<--The field Child.name is not visible
System.out.println("Previous id: " + child.id);
child.id = 100;//<--We can modify this because it is defined as public in Parent
System.out.println("Updated id: " + child.id);
}
}
The output will be:
Previous id: 0
Updated id: 100
For the next case, it seems that the question meant methods as in instance methods, not specifying whether or not there are static methods. Static methods that are public can be called anywhere and create side effects by modifying static fields and can also access private instance fields on instances of A, which makes A not immutable.
Point 2:
class B {
public int bValue;
}
class A extends B {
private int aValue;
}
An instance of A is not immutable because it has inherited a bValue field that can be changed.
Point 3:
class A {
private int x;
public static void mutate(A a) {
a.x += 1;
}
}
Instances of A can be mutated by calling the static method A.mutate, which has full access to A's private fields. The stipulation as it now reads, "all instance methods of class A in Java are private", does not apply to static methods.
All the previous answers were right. On the question regarding
A is not for sure immutable because you might be able to change its fields from static methods
can be achieved like
public class Test {
public static void main(String[] args) {
A a = new A(10);
System.out.println(a);
A.mutateObj(20);
System.out.println(a);
}
}
class A {
private static A a;
private int x;
A(int x) {
this.a = this;
this.x = x;
}
public static void mutateObj(int b) {
a.x = b;
}
#Override
public String toString() {
return "A{" +
"x=" + x +
'}';
}
}
Result =>
A{x=10}
A{x=20}
What I'm trying to do is instantiate an object in the parent class called "pObject" (assume the type to be protected Boolean). One child class which extends the parent class sets "object" to "true". The other child class which also extends the parent class will check to see if "object" is set to true.
Is this possible in Java?
public abstract class parentClassAction{
protected Boolean pObject;
}
public class childClass1Action extends parentClassAction{
super.pObject = true;
}
public class childClass2Action extends parentClassAction{
if(super.pObject!=null){
if(super.pObject == true){
System.out.println("Success");
}
}
}
You can make pObject static and access it as parentClassAction.pObject.
If you have 2 different instances of subclasses - they do not share any state. Each of them has independent instance of pObject, so if you change one object it will not be seen in another one.
There are many ways to solve your problem. The easiest way: you can make this field pObject to be static - it will work for simple example, but this can be also serious limitation (if you want to have more than one instance of pObject).
Yes. If pObject is static it will be shared:
public class Legit {
public static abstract class A {
protected static Boolean flag;
}
public static class B extends A {
public void setFlag(boolean flag) {
super.flag = flag;
}
}
public static class C extends A {
public boolean getFlag() {
return super.flag;
}
}
public static void main (String [] args) {
B b = new B();
C c = new C();
b.setFlag(true);
System.out.println(c.getFlag());
b.setFlag(false);
System.out.println(c.getFlag());
}
}
You can access non private fields of a super class using the syntax:
super.myBoolean = true;
Note: If the field has the default visibility (absence of modifier) it is accessible only if the sub class is in the same package.
Edited: I add information due to the new code added to the question.
It seems that you like to check a variable from two different objects. It is possible only if that variable is static. So declare it as protected static in the parent class. The rest of code rest the same.
So, one friend sent me this code and said that it had compiled successfully and returned 42.
But, the bothering thing is the method in parent class that "returns" 42 is private, and the method that is called on is in child class, and it's public. So, can anybody tell why and how this works?
static class A {
private int f() {
return 42;
}
}
static class B extends A {
public int f2() {
return super.f();
}
}
public static void main(String[] args) {
System.out.print(new B().f2());
}
It returns 42.
I tried to get rid of static, and
class A {
private int f() {
return 42;
}
}
class B extends A {
public int f2() {
return super.f();
}
}
public static void main(String[] args) {
Main m= new Main();
B b= m.new B();
System.out.print(b.f2());
}
it still returns 42.
Since both of the classes (A and B) are nested in Main, they can access the private int f() method.
If you extract the sources of A and B in top-level classes, this won't happen and you'll fail to compile.
The point of private is that "outside" classes should not be able to see private variables. But A and B are both part of the same class, or are nested within each other, so they can access each others private members.
So this will work:
public class A {
private void a() {
int bVal = this.new B().val; //! Accessing B private
}
class B {
A a = new A();
private int val = 10;
public void b() {
a.a(); // !! Accessing A private
}
}
BUT, this will fail, even if both A and B are in the same file but not within each other:
class A {
private void a() {}
}
class B extends A {
A a = new A();
public void b() {
a.a(); // can't see even if B extends A
}
}
This is because both classes A and B are nested inside another class, i.e both classes are inner classes of (or "part of") another same class. Since they (Data Members and Methods) are basically a member of the outer class,they are accessible within other inner classes even if private.
Java allows us Nesting of classes,If You Don't know about nested classes first read this :
http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
class Outer{
class A {
private int f() {
return 42;
}//Method f() is a private member of A and accessible by Outer
}
class B extends A {
public int f2() {
return super.f();
}//As class B is inner class of Outer it can access members of outer,thus indirectly member of A
}
public static void main(String[] args) {
System.out.print(new B().f2());
}
}
Is it possible to access a child class constant from within a static method in the parent class?
public class Model {
public static void someMethod(){
HERE I WANT TO GET THE MODEL_NAME constant!
}
}
public class EventModel extends Model {
public static final String MODEL_NAME = "events";
}
and in some other place I call:
EventModel.someMethod();
Try it!
If the constant is declared private, then no. If it is public, then yes, as anyone can access it. The parent class is largely irrelevent here.
class Parent {
public static void Foo() {
int x = Child.YEP; // Ok
int y = Child.NOPE; // Error
}
}
class Child extends Parent {
public static final int YEP = 42;
private static final int NOPE = 66;
}
Foo is defined in Parent, and thus cannot access private members of Child.
How about this?
class Parent {
abstract String getModelName();
public void someMethod() {
String myModel = getModelName();
}
}
class Child extend Parent {
String getModelName() { return "events"; }
}
Note however, that the method is no longer public.
You might find this more effective.
Define your parent class with a method getName. Note that this can be public, if you want your model class to expose a Name property, otherwise, you can keep it as "protected" as I have here. "Protected" will keep the method visible within this class, and any derived (child) classes.
public class Model {
private static String MODEL_NAME = "Model";
protected String getModelName(){
return MODEL_NAME;
}
}
Then define an "override" for the name method on your child class:
public class EventModel extends Model
{
private static String MODEL_NAME = "events";
#Override // Tells the compiler that this method OVERRIDES the parent method
public String getModelName(){
return MODEL_NAME;
}
}
This compiles and runs the way I suspect you are trying to acheive . . .
EDIT: Oooh. NOW I see the problem. Missed that you needed to reference that from a static method . . .
This is a question I was asked in an interview: I have class A with private members and Class B extends A. I know private members of a class cannot be accessed, but the question is: I need to access private members of class A from class B, rather than create variables with the same value in class B.
The interviewer was either testing your knowledge of access modifiers, or your approach to changing existing classes, or both.
I would have listed them (public, private, protected, package private) with an explanation of each. Then gone on to say that class A would need to be modified to allow access to those members from class B, either by adding setters and getters, or by changing the access modifiers of the members. Or class B could use reflection. Finally, talk about the pros and cons of each approach.
Reflection? Omitting imports, this should work:
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();
}
}
It'll not work if you do something like that before the of invocation 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);
}
}
});
And there are other conditions under which the Reflection approach won't work. See the API docs for SecurityManager and AccessibleObject for more info. Thanks to CPerkins for pointing that out.
I hope they were just testing your knowledge, not looking for a real application of this stuff ;-) Although I think an ugly hack like this above can be legit in certain edge cases.
The architecture is broken. Private members are private because you do not want them accessed outside the class and friends.
You can use friend hacks, accessors, promote the member, or #define private public (heh). But these are all short term solutions - you will probably have to revisit the broken architecture at some stage.
By using public accessors (getters & setters) of A's privates members ...
You cannot access private members from the parent class. You have make it protected or have protected/public method that has access to them.
EDIT : It is true you can use reflection. But that is not usual and not good idea to break encapsulation.
A nested class can access to all the private members of its enclosing class—both fields and methods. Therefore, a public or protected nested class inherited by a subclass has indirect access to all of the private members of the superclass.
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();
}
}
If I'm understanding the question correctly, you could change private to protected. Protected variables are accessible to subclasses but behave like private variables otherwise.
By using setters and getters u can access it
From JLS §8.3. Field Declarations:
A private field of a superclass might be accessible to a subclass - for example, if both classes are members of the same class. Nevertheless, a private field is never inherited by a subclass.
I write the example code:
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());
}
}
The explanation of the accessibility of InnerA.text is here JLS §6.6.1. Determining Accessibility:
Otherwise, the member or constructor is declared private, and 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.
You can use the setters and getters of class A. Which gives same feeling as if You are using a class A's object.
Have you thought about making them protected ? Just to be sure you are aware of this option, if you are then pardon me for bringing up this trivia ;)
Private members cant be accessed in derived class
If you want to access means you can use getter and setter methods.
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());
}
}
Private will be hidden until you have been given the right access to it. For instance Getters or setters by the programmer who wrote the Parent. If they are not visible by that either then accept the fact that they are just private and not accessible to you. Why exactly you want to do that??
I don't know about Java, but in some languages nested types can do this:
class A {
private string someField;
class B : A {
void Foo() {
someField = "abc";
}
}
}
Otherwise, use an accessor method or a protected field (although they are often abused).
A private member is accessible in subclass in a way that you cannot change the variable, but you are able to access the variable as read only.
Obviously, making them protected, or adding setters/getters is the preferred technique. Reflection is a desperation option.
Just to show off to the interviewer, IF "access" means read access, and IF Class A generates XML or JSON etc., you could serialize A and parse the interesting fields.
Class A
{
private int i;
int getValue()
{
return i;
}
}
class B extends A
{
void getvalue2()
{
A a1= new A();
sop(a1.getValue());
}
}
To access private variables of parent class in subclass you can use protected or add getters and setters to private variables in parent class..
You can't access directly any private variables of a class from outside directly.
You can access private member's using getter and setter.
Ways to access the superclass private members in subclass :
If you want package access just change the private fields to protected. It allows access to same package subclass.
If you have private fields then just provide some Accessor Methods(getters) and you can access them in your subclass.
You can also use inner class e.g
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 .You can also use Reflection e.g
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();
}
}
You can use Accessors (getter and setter method) in your Code.
By using setter method you can use else with the help of refection you can use private member of class by setting that member say a -
take a from class
and set a.setAccessible(true);
You may want to change it to protected.
Kindly refer this
https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html
If this is something you have to do at any cost just for the heck of doing it you can use reflection. It will give you list of all the variables defined in the class- be it public, private or protected. This surely has its overhead but yes, it is something which will let you use private variables. With this, you can use it in any of the class. It does not have to be only a subclass
Please refer to the example below. This may have some compilation issues but you can get the basic idea and it works
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();
}
}
Hope this be of some help.
Happy Learning :)
Below is the example for accessing the private members of superclass in the object of subclass.
I am using constructors to do the same.
Below is the superclass 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;
}
}
Below is subclass Guava which is inheriting from 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;
}
}
Below is the main function where we are creating an object of subclass and also displaying the member of superclass.
public class Main {
public static void main(String[] args) {
Guava G1=new Guava("kanpuria", "red");
System.out.println(G1.getName()+" "+G1.getType());
}
}
Note that a private field of a superclass might be accessible to a subclass (for example,if both classes are memebers of the same class),Nevertheless,a private field is never inherited
by a subclass
Simple!!!
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
}
}
thanks
Directly we can't access it. but Using Setter and Getter we can access,
Code is :
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
}
}
Modifiers are keywords that you add to those definitions to change their meanings. The Java language has a wide variety of modifiers, including the following:
Java Access Modifiers
Non Access Modifiers
To use a modifier, you include its keyword in the definition of a class, method, or variable. The modifier precedes the rest of the statement.
There is more information here:
http://tutorialcorejava.blogspot.in/p/java-modifier-types.html