Accessing parent member from child of child class - java

Today I faced a very odd interview question. The interviewer asked me:-
There is a class Parent and it has a method GetData. Class Child1 inherits Parent and Child2 inherits Child1. What you can do in Parent class so that the method "GetData" will be accessible from Child1 but not from Child2?

Kind of a weird setup, but here's another option that works because nested classes can access private members of the outer class:
public class Parent
{
public Parent()
{
GetData();
}
private void GetData()
{
}
public class Child1 : Parent
{
public Child1()
{
GetData();
}
}
}
class Child2 : Parent.Child1
{
public Child2()
{
GetData(); //compiler error, inaccessible due to protection level
}
}

Parent class can mark it's method as private, then declare the first Child inside of it's own declaration.
public class Job
{
private void Test()
{
}
public class JobChild : Job
{
public JobChild()
{
//works
this.Test();
}
}
}
public class JobChildTwo : Job.JobChild
{
public JobChildTwo()
{
//doesn't work
this.Test();
}
}

If we assume that Parent and Child1 exist in Assembly A while Child2 exists in Assembly B, and Assembly A does not expose its internals to Assembly B whilst Assembly B references Assembly A, then you can mark GetData as internal, at which point it will be accessible to Child1 but not Child2.
The side effect here is that it would be visible to the entire assembly.
Note that protected internal would have the opposite effect - it would make GetData visible to child2, since protected internal is explicitly "protected OR internal" as per MSDN

Related

Is it possible to chain overrided method call from top to bottom?

Suppose I have this hierarchy of classes
class Parent {
protected List<Object> things = new List<Object>;
public Parent() {
things.addAll(declareThings());
}
public List<Object> declareThings() {
// things declaration
}
}
class Child extends Parent {
public List<Object> declareThings() {
// additional things declaration
}
}
class GrandChild extends Child {
public List<Object> declarThings() {
// addtional things
}
}
I would like that creating an instance of say GrandChild, I get all the declared things in the hierarchy. Is it possible to implement such behaviour?
For each subclass, add a constructor where the first instruction is super();.

Java - Possible to create a parent class object that can store an instance of any subclass?

I know an array of a parent class can store an instance of any it's sub-classes but is this possible with a single object:
Here's an example of what I'm hoping to understand:
public class Parent
{
int a;
public Parent(int a)
{
this.a = a;
}
public void function1()
{
//Actions
}
}
public class Child1 extends Parent
{
public Child1(int a)
{
super(a);
}
public void function2()
{
//Actions
}
}
public class Child2 extends Parent
{
public Child2(int a)
{
super(a);
}
public void function3()
{
//Actions
}
}
Now if I perform the following:
Parent p1;
Child1 c1 = new Child1(5)
p1 = c1;
p1.function1();
p1.function2();
Would I be able to run the the function1 method of the Parent class as well as thefunction2 method of the Child1 class with the Parent class object p1?
Sorry if this is a silly question. I'm new to all this. Also, if this is a duplicate and you mark it as such, I'd appreciate that too.
After some more trial and error and additional research, I realize that what I'm hoping to achieve is not possible.
As such, for my project I created separate instances of each class and accessed them individually when required. That wasn't the solution I had in mind but it served as an effective workaround to my problem.
PS: To the comment that pointed out this code wouldn't work, they are right, it doesn't. It was meant as an abstract example to illustrate my issue. But perhaps I shouldn't have formatted it as a code then. I'll change that right away.

This keyword referring to a parent variable

Today a fellow learner came up with an interesting query. We know that this keyword is used to refer to the current object. But I could not explain to him how this keyword behaves as seen in the following snippet. I know what inheritance is: allows access to parent class variables and methods. But are they copied into the memory area of child instance?, because I am able to use this keyword to access the parent class property.
I was able to refer to parent class variable. I searched and found that nothing gets copied virtually to child class, but why the following behavior happens? Please explain this case of using this.
class Parent {
int a=10;
}
public class Child extends Parent{
void m1(){
System.out.println(a);
System.out.println(this.a);
System.out.println(super.a);
}
public static void main(String[] args){
new Child().m1();
}
}
https://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html
https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
The property a is inherited by Child. Therefore, you can use this.a in child to reference it.
Where was the problem supposed to be?
I searched and found that nothing gets copied virtually to child class
You have the wrong example to illustrate that statement.
The way to understand that is (roughly): "instance variables are not overridden when re-declared in subclasses, so you can't declare an instance as Parent and expect to get Child.a if the instance was created with new Child()". Here's an example of the problematic case:
class Parent {
int a = 10;
}
public class Child extends Parent{
int a = 12; //not overridden
public static void main(String[] args){
Parent child = new Child();
System.out.println(child.a); //This will print 10, not 12
}
}
System.out.println(child.a); will print 10 because variables instance fields don't get overridden. You get the value based on the declared type (Parent in this case)
When you instantiate a class Child it contains all members of itself and of Parent. However, private members of Parent are not accessible from Child:
class Parent {
private int p = 10;
}
public class Child extends Parent{
void m1(){
System.out.println(p); // compilation error
}
}
Another interesting case is when one instance of Parent tries to access a private field of another instance of Parent. What do you think happens?
public class Parent {
private int p = 11;
public boolean same(Parent other) {
return other.p == p;
}
}
You might think other.p will result in a compilation error since p is a private field. However, since privacy does not pertain to object instances, but to classes. So all private fields in Parent are visible within all Parent instances, so this works!
Consider below Code:
this is a reference variable which will point to the current object.
super is used to refer to Parent's property in case you have created
the same in the child.
class Product{
String color;
public Product() {
color = "Black";
}
}
class Mobile extends Product{
String color;
Mobile(){
color = "White";
}
void showMobileData(){
System.out.println("this hashCode is "+this.hashCode());
System.out.println("super hashCode is: "+super.hashCode());
System.out.println("color is: "+color);
System.out.println("this.color is: "+this.color);
System.out.println("super.color is: "+super.color);
}
}
public class Test {
public static void main(String[] args) {
//new Mobile().showMobileData();
Mobile mRef = new Mobile();
System.out.println("mRef HashCode: "+mRef.hashCode());
mRef.showMobileData();
}
}

Java - calling a method by passing child instance to a function with parameter of parent class type [duplicate]

public class Parent {
....
}
public class Child1 extends Parent {
....
public void foo() {
....
}
}
public class Child2 extends Parent {
....
public void foo() {
....
}
}
Here method foo() only exists in the Child classes and CAN NOT be added to the Parent class (not even abstract method). In this situation when I want to call the foo() method on obj which is Parent class's reference then I need to use intanceof with multiple if..else which I want to avoid.
Parent obj = ...// Object of one of the child classes
obj.foo();
EDIT: I Need to use type of obj as Parent only. Else I will not be able to call methods on obj which exists in Parent class.
My Solution: The approach that I am thinking is to define an interface say FooInterface with foo() method and let all the child classes implement it, then I could just type cast the obj to that interface and call foo() method like this:
if(obj instanceof FooInterface){
((FooInterface)obj).foo();
}
Is there a better approach ? Or any improvement to this one?
You can't do it with parent object reference until an unless method is declared in parent class/interface itself.
You have to downcast it to child class because parent class/interface doesn't have any knowledge about the child class other than the contract defined between them.
Here contract means abstract methods.
you can try in this way where there is no need to put a check it.
FooInterface sc =new Child1();
sc.foo();
...
interface FooInterface{
void foo();
}
public class Parent {
}
public class Child1 extends Parent implements FooInterface{
public void foo() {
}
}
public class Child2 extends Parent implements FooInterface{
public void foo() {
}
}
The approach that I am finally taking is to define an interface say FooInterface with foo() method and let all the child classes implement it, then I could just type cast the obj to that interface and call foo() method like this:
Parent obj = ...// Object of one of the child classes
.....
if(obj instanceof FooInterface){
((FooInterface)obj).foo();
}
The polymorphism is applied on object reference, not a type. When you call
FooInterface obj = ...// Object of one of the child classes
obj.foo();
the child class method foo() is called.
If you want to typecast only then there is no need of adding interface. You can typecast it to your desired class and call the method. Example
public class HelloWorld {
public static void main(String args[]) throws FileNotFoundException {
SuperClass sc =new Child1();
if(sc instanceof Child1)//Do same for Child2
((Child1)sc).foo();
}
}
class SuperClass {
}
class Child1 extends SuperClass{
public void foo(){
System.out.println("From child1");
}
}
class Child2 extends SuperClass{
public void foo(){
System.out.println("From child2");
}
}
Output :
From child1
You could implement an AbstractChild inheriting from Parent and then extend this class instead of Parent:
public class Parent {
....
}
public abstract class AbstractChild extends Parent{
public abstract void foo();
}
public class Child1 extends AbstractChild {
....
public void foo() {
....
}
}
public class Child2 extends AbstractChild {
....
public void foo() {
....
}
}
So you need to only check if your instance is instanceof AbstractChild.

How can i break the inheritance nature in java?

I have below parent class :-
class Parent {
Parent() {
System.out.print("Parent ");
}
}
class Child extends Parent {
Child() {
System.out.print("Child");
}
}
So when i execute Child c = new Child();
My output should be "Child" Not "Parent Child"
can we do that using reflection API?
Requirement :-
I have a long Junit Setup hierarchy Which I want to avoid for some of the classes
What happens is when you create the Child class the Parent's class constructor is called first and then the Child's constructor.
What you could do if you must change what happens in the parent constructor is that you extract the related code into a protected method and this way you can override it in the Child class
However it is error prone and not recommended (What's wrong with overridable method calls in constructors?)
class Parent {
Parent() {
overridableInit();
}
protected void overridableInit() {
System.out.print("Parent ");
}
}
//If you want to extend the behavior:
class Child1 extends Parent {
#Override
protected void overridableInit() {
super.overridableInit();
System.out.print("Child1 ");
}
}
//If you want to skip the Parent behavior:
class Child2 extends Parent {
#Override
protected void overridableInit() {
System.out.print("Child2 ");
}
}

Categories