I have a class with many subclasses,but when passing a subclass instance to some method which is supposed to receive an instance of the superclass, the attribute of the subclass is overwritten.
For example, the following code prints 0. What should I do to it so that it prints the subclass parameter value?
class A{
int cost;
}
class B extends A{
int cost = 10;
}
class Test{
public static void main(String[] args){
B b = new B();
method4A(b);
}
static void method4A(A a){
System.out.println(a.cost);
}
}
While fields can be shared within inheritance, given the right access modifiers (i.e. anything not private pretty much - default access will not work across different packages though), they are resolved at compile time, contrary to methods which are resolved at runtime (the latter is called virtual method invocation).
ints default to 0, and you're passing an A reference type, so A.cost's value of 0 is printed.
You have a range of options here:
Do not declare cost in B and assign cost value from A in B's constructor, or instance initializer, etc. to 10
An ugly, explicit cast in method4A, e.g. System.out.println(((B)a).cost);
Passing a B reference type instead of A in method4A
Keep both cost variables and declare a simple getter in A returning cost, and #Override it in B with the same implementation (it'll return B's cost even when invoked on a A reference if the instance actually is B)
Your problem doesn't have any relation with the overriding.
Declaring twice the same field in both classes (class and subclass) may be error-prone.
Do you really need to define two distinct fields ?
Why not reuse the field of the parent class in the subclass or provide a access to ?
Of course, in some specific cases, it is acceptable and desirable to define two distinct fields but for these cases generally you use the private modifier to isolate them.
A natural way to define such as behavior is providing a private field for cost and getter and setter in the parent class.
In this way, the subclass has way to value/set this field.
It could for example value the field from its constructor :
class A{
private int cost;
public void setCost(int cost){
this.cost = cost;
}
public int getCost(){
return cost;
}
}
class B extends A{
public B(){
this.setCost(10);
}
}
class Test{
public static void main(String[] args){
B b = new B();
method4A(b);
}
static void method4A(A a){
System.out.println(a.getCost());
}
}
You can use method overriding with getters like this:
class A {
int cost;
public int getCost() {
return cost;
}
}
class B extends A {
int cost = 10;
public int getCost() {
return cost;
}
}
class Test {
public static void main(String[] args) {
B b = new B();
method4A(b);
}
static void method4A(A a) {
System.out.println(a.getCost());
}
}
I'm new to java. Recently I saw some code which was similiar to this:
class A {
protected int myInt;
public static void main(String[] args) {
B b = new B();
b.myFunction();
}
}
class B extends A {
public void myFunction() {
this.myInt = 10;
}
}
As far as I know, when creating a subclass instance, an instance of its parent is created as well. All protected and public members of base class are accessible from the subclass.
If I override myInt there will be a difference between this.myInt to super.myInt because each class will have its own myInt (B will have access to both).
So, my question is: if I don't override myInt, which form is preferable, this.myInt or super.myInt?
You only need to use this or super when need to specify which scope are you using/referring to. In your case, I'll prefer to omit the this to simplify the readability.
super is used to represents the current instante of a parent class while this is used to represents the current class. You only need to used this or super if some variable or method overlaps (Have the same name) with one in a wide scope.
eg. If you have define a method parameter with the same name as class attribute, you need to use this to indicate that you are using the class attribute and not the method parameter.
public class A {
public int myInt = 1;
public static void main(String[] args) {
B b = new B();
b.myFunction(3);
}
}
class B extends A {
public int myInt = 2;
public void myFunction(int myInt){
System.out.println(myInt); // The parameter
System.out.println(this.myInt); // myInt from the current class (B)
System.out.println(super.myInt); // myInt from the parent class (A)
}
}
This example will print:
3
2
1
If you don't have this kind of collission, the use of this is optional:
public void myFunction2(){
System.out.println(myInt); // Both refers to the same
System.out.println(this.myInt); // variable myInt from class B
}
It's a matter of taste and the project's standards/guidelines more than anything else.
Personally, I wouldn't use either, and would just write myInt = 10.
Only one instance is created. If you instantiate a derived object, the parents constructor is called, but only one object is created. Also, the term this is more so used when there are different variables with the same name being referenced in a class.
For example a simple constructor:
class SupClass{
public int a = 1;
int incA(){
return ++a;
}
}
class MyClass extends SupClass {
public int a = 10;
public int b = 20;
MyClass() {};
MyClass(int a, int b){
this.a = a;
this.b = b;
}
int incA(){
return ++a;
}
public static void main(String args[])
{
SupClass d = new MyClass();
System.out.println(d.a); //1, members known of type SupClass at compile-time,
System.out.println(d.incA()); //11, methods are virtual, decided at run-time
}
}
Only use the super method when you want to explicitly use the value that is in the super class. To answer your question, only methods can be overwritten, member variables can not.
For example I've got simple class
class Simple {
private int i = 6;
private static void method(Simple obj) {
System.out.println("Value i: " + obj.i);
}
public void method() {
method(this);
}
public static void main(String[] args) {
new Simple().method();
}
}
Why I can get access to i in static method?
private members can be accessible with in the class. Your static method belongs to the same class. Hence you can access.
Modifier Class Package Subclass World
---------------------------------------------
private **Y** N N N
Update: To avoid the confusion, move the static method to other class and try once.
Don't get confused with static and private/public/[default]. Those are two separate things. A static function can access private non-static field because it is part of the class. And thats whats private does, only restricting access to the class level, without any distinction being made between static or not.
If it's the staticness that's bothering you, obj is a proper "not static" object, which us why it has an accessible non-static field. The method being static is irrelevant.
you are accessing instance of object not directly class variable. when you use direly "i" without reference to object its not allowed.
Private variable visibility is by default in with in class access .
public class Simple {
private int i = 6;
private static void method(Simple obj) {
System.out.println("Value i: " + i); //compile Error ::Cannot make a static reference to the non-static field i
}
public void method() {
method(this);
}
public static void main(String[] args) {
new Simple().method();
}
}
Recently, I observed an unexpected behavior of accessing priavte fields in Java. Consider the following example, which illustrates the behavior:
public class A {
private int i; <-- private field!
public A(int i) {
this.i = i;
}
public void foo(A a) {
System.out.println(this.i); // 1. Accessing the own private field: good
System.out.println(a.i); // 2. Accessing private field of another object!
}
public static void main(String[] args) {
(new A(5)).foo(new A(2));
}
}
Why I am allowed to access the private field of another object of class A within the foo method (2nd case)?
Private fields protect a class, not an instance. The main purpose is to allow a class to be implemented independently of its API. Isolating instances between themselves, or protecting the instance's code from the static code of the same class would bring nothing.
This is because they are of the same class. This is allowed in Java.
You will need this access for many purposes. For example, in an implementation of equals:
public class A {
private int i;
#override public boolean equals(Object obj){
if(obj instanceof A){
A a = (A) obj;
return a.i == this.i; // Accessing the private field
}else{
return false
}
}
}
The foo method belongs to the same class as does the variable i there is no harm in allowing such an access.
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