I've seen answers for questions related to mine on Stack Overflow, but I am still left with some ambiguity. A parent class method has access to its own private instance variables. If a child class inherits the class, what happens when the getA() method is called on an instance of the Child class? Does it return the a from the Parent class or the a from the Child class?
class Parent {
private int a = 10;
public int getA() {
return a;
}
}
class Child extends Parent {
private int a = 22;
}
public class Test {
public static void main(String []args) throws Exception {
Child c = new Child();
System.out.println(c.getA());
}
}
As the Method getA() is inherited, if you call this Method, you'll always invoke the Parent's Method.
The current Object will be treated as a Parent and not as a Child, and the Parent's a will be returned.
Even though you have your own variable a, this variable wont override the Parent's a. They are different from each other, have different addresses and different values.
If you want getA() to return Child's a, you need to override the Method to return your new variable.
class Child extends Parent {
private int a = 22;
#Override
public int getA(){
return a;
}
}
You could also "go crazy" and do stuff like the following:
class Child extends Parent {
private int a = 22;
#Override
public int getA(){
int superA = super.getA();
return a+superA;
}
}
That way you could return the sum of Parent's and Child's a.
(Just an example)
This is a duplicate of this SO post.
The variable a in subclass Child hides the a in the parent class Parent.
Private variables are local to the class and in your code you are inheriting the properties of the parent class so you can access getA() and it will return the parent's attribute.
And you cannot access child's variable unless you have public getter method for child attribute.
Stick to basics "private member variable will only be accessed within the class by its own member functions and fields cannot be inherited" so basically when you are accessing the private variable A in parent class , the method is supposed to access its own private member rather then the private field of any child class.
Fields cannot be overridden.
In your code, an instance of child (like the one referred to by c) has two different fields, which are both called a.
You cannot access Parent's private variables inside Child, full stop. That's the entire point of private. There is nothing* you can write inside Child to make the parent's a field equal 22.
* Technically, you could with reflection. Reflection doesn't count though, since its purpose is essentially to allow you to break things, and do things that are otherwise impossible.
Related
I'm designing a class hierarchy and I come across the problem as my title, here is a smaller abstraction of it:
public abstract class A {
private C c;
public A(C c) {
this.c = c;
}
// ...
}
public class B extends A {
private int a;
private int b;
// ...
public B(int a, int b, ... /* and more but no object of C */) {
super(new C(this)); // <-- this is the point, got error:
// can't access `this` .
this.a = a;
this.b = b;
// ...
}
}
public class C {
private A a;
public C(A a) {
this.a = a;
}
}
In short: A needs to keep a reference to C, vice versa, but both should be done in their constructor, and after the construction of both, the fields A a and C c should not be changed so I made them private. So in this situation what's the best practice?
The following is actually not a good example, but the point is that I have a situation need to do what the above try to do.
(More context: Now let's say I change private C c; of class A into
private List<C> someCs;
that is: A is a container of C's, so during some situation those C's need to be sorted. And for some client of each C, the client needs to know what's its parent, i.e. which A it belongs to. In this situation I need references of both directions.)
this is not a valid reference for other objects until after the constructor is done. for that reason this kind of cyclic dependency (parent with reference to child and child with reference to parent) cannot be initialized in the constructor. the parent child references also cannot be final because final must be initialized in the constructor.
you could write a factory that initializes all the parents and children. then after all are initialized you can cross reference them. but this needs child.parent and parent.child to be accessible to the factory. either they are public or have a public setter. you can do some other stunts to allow the factory to set a private variable in the parents and children but i do not recommend that.
here is one suggestion for your situation: create an object which tracks the mapping between parents and children. the mapping has method getParent(this) called from child when it needs its parent. and methods getChildren(this) and getChildrenSorted(this) called from parent when it needs its children.
the mapping can be initialized once and then locked down using private and final and whatnot preventing further changes during runtime. every parent and child can then get a private and final reference to this object.
for more information:
http://www.javapractices.com/topic/TopicAction.do?Id=252 Don't pass 'this' out of a constructor
Passing "this" in java constructor
Why must a final variable be initialized before constructor completes?
How can I initialize interdependent final references?
So I have these two classes:
Parent
public class MyClass {
protected int myVal;
public MyClass(int val) {
setMyVal(val);
}
private void setMyVal(int val) {
myVal = val;
}
}
Child
public class SubClass extends MyClass {
public SubClass(int val) {
super(val);
}
private void setMyVal(int val) {
myVal = val + 1;
}
}
Which setMyVal will be called when a child class is created?
I have a lot of child classes that need to have their myVal set with different logic, including the parent class.
So for instance, if I make a parent class instance it will need to simply set myVal to the val passed in. If a child class instance is created it will need to set myVal in a completely different way, and have nothing to do with the way the parent class myVal is set. Is this the correct way to do this?
The child class or SubClass is going to override any method(apart from private ones) coming from the parent class, most popular one is toString where every class extends Object which contains toString() method, but the one implemented in your child class is the one that gets called.
According to App Shah in Cruchify, he gave some nice rules to note when overriding methods here
Rules for method overriding:
In java, a method can only be written in Subclass, not in same class.
The argument list should be exactly the same as that of the overridden
method.
The return type should be the same or a subtype of the return
type declared in the original overridden method in the super class.
The access level cannot be more restrictive than the overridden
method’s access level. For example: if the super class method is
declared public then the overridding method in the sub class cannot be
either private or protected.
Instance methods can be overridden only
if they are inherited by the subclass.
A method declared final cannot
be overridden.
A method declared static cannot be overridden but can
be re-declared.
If a method cannot be inherited then it cannot be
overridden.
Read more Few rules with examples, so you understand it and hopes it helps.
Private method is not inherited. If you want to override method of existing method of parent class, please use public or protected.
In case of overriding, method of subclass is called. This explains how polymorphism comes to work.
You can define many different classes inheriting same interface(or abstract class). They have different implementation details, but can be operated using same interface.
First of you don't need to call the setValue(val) in the constructor of the parent class
the best way to create your constructor is with the parameter:
public MyClass(int val) {
this.myVal = val;
}
if want the behavior of a method to be different in a subclass, you need to override it:
#Override
protected void setValue(int val){
myVal = val + 1;
}
also make the methods protected instead of private
I hope this helps
It was my understanding that a child cast to the parent type (as in Super sc = new Child();) would call the parent class's static methods, and access the parent class's non-hidden fields, but would make use of the child class's instance methods.
This does not seem to hold true for the case of private instance methods (those in which overriding does not actually take place because the parent method is private.)
I understand that the fact that there is no overriding (private parent methods are not visible to the child, so they can only be hidden.) would mean that the child wouldn't look up the heirarchy to see the parent's version of the method when the instance method is invoked from the child.
However, the exact opposite of what I'd expect (the version present in the child being called) is occurring. The parent version of the private method is invoked.
Why does this happen if the instance methods of the child are typically invoked, and within the child, there is a method with an identical signature (a perfect match for the invocation of method2() in this case) already present, hiding the same method in the parent class?
package whatever;
public class A {
public void method1(){
System.out.println("A method1().");
}
//using "final" here to emphasize that this is a hiding, not an override.
private final void method2(){
System.out.println("A private method2().");
}
public static void main(String[] args)
{
A a = new A().new B();
a.method1(); //calls B method 1
((A.B)a).method1(); //calls B method 1
a.method2(); //calls A private method 2 **I expected it to call B private method 2
((A.B)a).method2(); //calls B private method 2
}
public class B extends A {
public void method1(){
System.out.println("B method1().");
}
private final void method2(){
System.out.println("B private method2().");
}
}
}
First, B is actually a nested class and, oddly enough, the private members of nested classes can by accessed by the outer class. Otherwise, it wouldn't even be legal to do ((A.B)a).method2(); (The reverse is also true. B can access private members in A as well.)
That said, to answer your actual question, the reason a.method2(); calls the private method in A is that private methods are not virtual, as they cannot be overriden at all. (How could they be, if inheriting classes aren't supposed to even know about them?) As such, they are bound at compile time, which means using the declared type of the variable. A a is declared as A, but (A.B)a is cast at compile time to B. Thus, your first call uses the private method from A and your second call uses the private method from B.
It's quirky that the facts in those two paragraphs don't interact with each other. It might reasonable to expect that, since the nested class "knows" about the outer class's private members, an override might be possible. But it's not. Private functions never show up in the vTable and can never be overridden.
Short answer: because your B class is in the same file (.java) with the one that contains #main() method.
The reason that the private method of the parent class is visible to the child class is that the child class is an inner class of its parent class in your case.
Non-static nested classes (inner classes) have access to other members of the enclosing class, even if they are declared private
Please help me to understand how inheritance works.
If I have two classes, parent and child. When I create an instance of child is parent class instance constructed as well or not?
My code of Parent class.
public class Parent {
private char s;
#Override
public int hashCode() {
return s;
}
}
And Child
public class Child extends Parent {
private int i;
public Child(int i) {
super();
this.i = i;
}
#Override
public int hashCode() {
return i;
}
}
And finally the test
public class Main {
public static void main(String[] args) {
Child child = new Child(100);
System.out.println(child.hashCode());
System.out.println(child.getClass().getSuperclass().hashCode());
}
}
In output I get
100
2000502626
So the hashes of objects are different. It means that when I create instance of Child it is also created instance of Parent. Am I right?
Your question has nothing to do with inheritance.
the 100 you get from child instance's hashcode() method, as you expected.
The 2000502626 was from Parent.class, not Parent object.
Parent.class has type java.lang.Class
parent object has type Parent
When you create a Child object a Parent constructor is invoked as well, because a Child is a Parent.
But when you do this:
System.out.println(child.getClass().getSuperclass().hashCode());
you're not invoking Parents instance hashode. You are invoking hashCode() of the instance of the Class object.
See what child.getClass().getSuperclass() returns. It returns an instance of type Class not of type Parent/Child.
You cannot invoke Parents instance methods using child.getClass().getSuperClass() - that doesn't return the instance of a type, but an object representing this type.
Try doing this in child method:
#Override
public int hashCode() {
System.out.println("In child hashCode: " + i);
System.out.println("Parents hashCode: " + super.hashCode());
return i;
}
This will return 100 and 0, as Parents s hasn't been initialized.
Actually, there will be just one child object created. Since every child is a parent, the parent constructor will be invoked. if you print this in both child as well as parent instance methods, it will print the same (child object)
check - this question
If I have two classes, parent and child, When I create an instance of child is parent class instance constructed as well or not?
Yes. It works through Constructor. When you call constructor of your child class to create object, it first calls its parent class contructor and hence creates object of parent class
Yes. Both parent and child object are created. The child class constructor calls the parent(super) class constructor first, then only other functions of the child class are performed. As you can see from your own code two different values getting printed.
In the following code, the constructor of Child has reduced visibility from public to private, which is allowed. The inherited methods, such as test(), cannot have reduced visibility. Why does Java operate this way?
class Parent {
public Parent(){}
public void test()
{
System.out.print("parent test executed!");
}
}
class Child extends Parent{
private Child(){}
private void test(){
System.out.print("child test executed!");
}
}
Constructors are not inherited, so Child() doesn't override Parent().
As for the methods, if you have (if Child() were public)
Parent p = new Child();
p.test();
Had it been allowed, this would be invoking a private method. So narrowing the access while overriding is not permitted.
When extending a class you are stating that your class is an extension of the parent class ("IS-A" relationship). What this means is that your class will have all methods of your parent class. This is the same as implementing an interface in java except you gain the method definitions (and fields) from your parent and not just methods declared in the interface. In interfaces constructors are not present because they are not methods. Constructors are special as they belong entirely to the class they are declared on. They declare how to construct only themselves.
In order to construct an object you must know that objects class.
class A {
private message;
private A() {
message = "You created an A";
}
public A(String message) {
this.message = message;
}
public void printMessage() {
System.out.println(message);
}
public static A createAnA() {
return new A();
}
}
class B extends A {
public B() {
super("You created a B");
}
}
A anA = new B(); // This will work
A anotherA = new A(); // This is not allowed as the constructor is private
A yetAnotherA = A.createAnA(); // This works too
So when we constructed B we can say that it is an A. Even though the constructor A is private this is due the constructor not being a part of the interface. The only thing we are saying about B when we assign it to a field of type A is that it has the methods of declared in A. In this case printMessage and createAnA.
That is why you can make the constructor private without changing the definition of the class. Now, why are you not allowed to make the method private when overriding a parents signature. This comes to having varying definitions of the [class].method(). Let's say that you could make your method private. Let's say that you declared a printMssage in the B class. Your reasoning is that you want that method for your use only inside the method and you want your parents printMessage to be used when called externally. Now, you wrote a method like this in the B class.
public void adjustMessage(String additional) {
message = getMessage() + additional();
}
Which version of get message would be executed? Your private one or the public one of your parents? The Java dispatcher would of course choose the public one as it is the one declared in the interface. So we we look at this example we can see if you did make your method have different a lower privilege your method could never be dispatched too which would just make things confusing for the reader.
This is a very good question.