As shown below, I tried to cast the object of the sub-class to that of its parent class. That went well. But, when I try to access the overridden method of the parent class, it doesn't happen. Instead the overriding method in the child class is called. I know I can do this using the super keyword, but I just want to know why this can't be done by casting?
This is the parent class:
public class Parent {
public void print() {
System.out.println("In parent");
}
}
This is the child class which has its properties inherited from the parent class:
public class Child extends Parent{
public void print() {
System.out.println("In child");
}
}
This is the class which contains the main method:
public class Main {
public static void main(String[] args) {
Child child = new Child();
((Parent)child).print();
}
}
Clarification
In your example, the object is always Child. Casting is applied only to the reference variable. This casting never impacts the actual object.
Options
As mentioned by others, add a separate method that will call super.() or use hiding. Hiding is not actually overriding.
Beware of the side effects of hiding
public class AccessParent {
public static void main(String[] args) {
Parent p = new Child();
p.methodC();
System.out.println(new String(new char[20]).replace("\0", "-"));
p.methodD();
}
}
class Parent {
void methodA() {
System.out.println("Parent.methodA");
}
private void methodB() {
System.out.println("Parent.methodB");
// this will still call Child.methodA
// a hidden method can not control the scope of overridden method
methodA();
}
void methodC() {
System.out.println("Parent.methodC");
methodB();
}
void methodD() {
System.out.println("Parent.methodD");
// hidden method will be called
// technically Child.methodB() is not overridden
methodB();
}
}
class Child extends Parent {
#Override
void methodA() {
System.out.println("Child.methodA");
}
// this not overridden
void methodB() {
System.out.println("Child.methodB");
}
}
This will output
Parent.methodC
Parent.methodB
Child.methodA
--------------------
Parent.methodD
Parent.methodB
Child.methodA```
You can't access a overriden method directly from a child class. The best you can do is add another function to your child that calls the parent print function.
public class Child extends Parent{
public void print() {
System.out.println("In child");
}
public void printParent() {
super.print()
}
}
Then you can access it like this,
public class Main {
public static void main(String[] args) {
Child child = new Child();
child.printParent();
}
}
Overriding is a principle which gives weightage on inheritance.
If you have a specific requirement to behave as per the casting then the method must be class level "static" instead of instance level.
You would loose the beauty of true inheritance and enter in hiding it more. However, the same can be achieved in casting way
package com.company.language;
public class InheritanceTrial {
public static void main(String[] args) {
Child child = new Child();
child.print();
((Parent)child).print();
}
}
class Parent {
public static void print() {
System.out.println("In parent");
}
}
class Child extends Parent{
public static void print() {
System.out.println("In child");
}
}
With the help of java.lang.invoke.MethodHandles, java.lang.invoke.MethodHandle and java.lang.invoke.MethodType we can only access the immediate parent's method. So this might help your question.
Working solution
public class Child extends Parent {
public static void main(String[] args) throws Throwable {
MethodHandle MH_Parent = MethodHandles.lookup().findSpecial(Parent.class, "print" , MethodType.methodType(void.class), Child.class);
MH_Parent.invokeExact(new Child());
}
public void print() {
System.out.println("In child");
}
}
class Parent {
void print() {
System.out.println("In parent");
}
}
Failing Solution
class Parent {
public void print() {
System.out.println("In parent");
}
}
class Child extends Parent{
public void print() {
System.out.println("In child");
}
}
public class Main {
public static void main(String[] args) throws Throwable {
MethodHandle MH_Parent = MethodHandles.lookup().findSpecial(Parent.class, "print" , MethodType.methodType(void.class), Child.class);
MH_Parent.invokeExact(new Child());
}
}
Related
This question already has answers here:
Java order of Initialization and Instantiation
(2 answers)
Closed 5 years ago.
I know, there is an implicit super() statement in the constructor of the subordinate class, but how do the class fields, instance fields, and constant fields are initiated and their order in super class and subordinate class, also where are the method information stored?
As demonstrated below, the output of the program is "null", but it will be "child" if I add the static modifier before s in the child class. I suppose that to explain such result, the answer to the questions above is essential.
public class Parent {
private String s = "parent";
public Parent() {
call();
}
public void call() {
System.out.println(s);
}
public static class Child extends Parent {
private /*static*/ String s = "child";
public Child() {
}
public void call() {
System.out.println(s);
}
}
public static void main(String[] args) {
Child child = new Child();
}
}
you can create constructor with parameters like this
in parent class
public Parent(String s) {
this.s = s;
call();
}
and child class constructor
public Child() {
super(this.s);
}
when you are declaring Child Constructor his first line is super()
with default ;
and it is calling Parent class's constructor and Parent class's call method.
you can also do like this
public class Parent {
private String s = "parent";
public Parent(String ss) {
call(ss);
}
public void call(String ss) {
System.out.println(ss);
}
and child class
public static class Child extends Parent {
private String s = "child";
public Child() {
super(this.s);
}
}
public static void main(String[] args) {
Child child = new Child();
}
}
you don't need call() method in child class anymore because you have it in parent class and you can access this method from child class too .
I want to know whether a child class calling parent method that invokes an overloaded method in the parent class, will invoke the overloaded method in the child class
class Parent {
void doStuff() {
}
void asd() {
doStuff();
}
}
class Child extends Parent {
void doStuff() {
// implementation
}
}
static void main(Args... args) {
new Child().asd(); -> does this invoke the doStuff with the implementation or the empty doStuff in the parent class?
}
class Parent{
void doStuff(){
System.out.println("parent class");
}
void asd(){
doStuff();
}
}
class Child extends Parent(){
#Override
void doStuff(){
//super.asd();
System.out.println("child class");
}
}
/**
* When you run the program you will see the two methods being called
* one from the parent class and then the override method for child.
* just uncomment the super.asd() in childs doStuff() to see both print.
**/
public static void main(String [] args){
Child c = new Child();
c.doStuff(); // call methods
}
interface Y {
void search(String name);
}
class A implements Y {
void search(String name) {
//Is it possible to say: "If I was called from class B then do a search("B");
}
}
class B extends A {
}
public class Main {
public static void main(String[] args) {
B b = new B();
b.search();
}
}
Given the above code is it possible to reason in superclass which subclass was used for calling a method?
The reason I want to do this is because the code in Search is very similar for all Subclasses, the only thing that changes is the Classname, so I thought there is no need to Override in each subclass. I have updated the code to reflect this. Please let me know if there is a better way of doing it/
Calling this.getClass() inside your search method will give you the concrete class of the current instance.
For example:
class Example
{
static class A {
public void search() {
System.out.println(getClass());
}
}
static class B extends A {}
public static void main (String[] args) throws java.lang.Exception
{
new A().search();
new B().search();
}
}
outputs
class Example$A
class Example$B
The cleanest way to do it is to override the method in each subclass.
interface Y {
void search();
}
class A implements Y {
public void search(){
search("A");
}
protected void search(String name) {
// implement your searching algoithm here
}
}
class B extends A {
public void search(){
search("B");
}
}
public class Main {
public static void main(String[] args) {
B b = new B();
b.search();
}
}
That's the way inheritance is suppose to works. A super class should not know its subclasses.
And, in case you extends your class B, you can easily either:
-Keep the same behaviour as B:
class C extends B {
// do nothing, when calling search, it calls the method implemented in B
}
-Change the behaviour to search for "C"
class C extends B {
public void search(){
search("C"); // or search("whateveryouwant")
}
}
You can simply override the method in class B.
The other way could be to write the search() method as
void search() {
if (this.getClass().equals(B.class)) {
//The logic for B
} else if (this.getClass().equals(A.class)) {
//The logic for A
}
}
You have to provide the fully qualified name for the class.
Better follow template pattern.
interface Y {
void search(String name);
}
abstract class AbstractionTemplate implements Y{
#Override
public void search(String name) {
//a lot of code.
System.out.println("common stuff start");
doImplspecificStuffOnly();
System.out.println("common stuff end");
//a lot of code.
}
abstract void doImplspecificStuffOnly();
}
class A extends AbstractionTemplate{
#Override
void doImplspecificStuffOnly() {
System.out.println("a's stuff");
}
}
class B extends A {
#Override
void doImplspecificStuffOnly() {
System.out.println("B's stuff");
}
}
public class Main {
public static void main(String[] args) {
B b = new B();
b.search("hey");
}
}
I am creating child class object. I know parent class constructor called first .If i want to call parent class print method so I am used this.print() but this is not working.
Please suggest me how to call parent class print() method without creating parent class object.
public class Test
{
public static void main(String[] args)
{
Child Child = new Child();
}
}
class Parent
{
void print()
{
System.out.println("parent class print method");
}
Parent()
{
this.print();
}
}
class Child extends Parent
{
void print()
{
System.out.println("child class print method ");
}
}
in child constructor You can call a super class method like :
super.print();
see java docs
public class Superclass {
public void printMethod() {
System.out.println("Printed in Superclass.");
}
}
public class Subclass extends Superclass {
// overrides printMethod in Superclass
public void printMethod() {
super.printMethod();
System.out.println("Printed in Subclass");
}
public static void main(String[] args) {
Subclass s = new Subclass();
s.printMethod();
}
}
To call any parent method use super. This also works for the constructor:
class Child extends Parent
{
void print()
{
System.out.println("child class print method ");
}
Child() {
super.print(); // parent print method
this.print(); // child print method
}
}
"this" keyword refers to current class and "super" keyword refers to its parent class or interface which it extends or implements respectively.
Clear my concept thanks to anwser my question..
public class Test
{
public static void main(String[] args)
{
Child Child = new Child();
}
}
class Parent
{
void print()
{
System.out.println("parent class print method");
}
Parent()
{
this.print();
}
}
class Child extends Parent
{
void print()
{
super.print();
}
}
output:
parent class print method
I have the following code:
public class GrandParent {
public void greet() {
System.out.println("Hello from grandpa.");
}
}
public class Parent extends GrandParent {
public void run() {
greet();
}
}
public class RunMe {
public static void main(String args[]) {
Parent p = new Parent();
p.run();
}
public void greet() {
System.out.println("Hi.");
}
}
I am tasked to write the class RunMe and as much as possible, I am not allowed to modify classes Parent and GrandParent. How can I implement this in such a way that when execution reaches run() of Parent, the greet() of RunMe (or it could be in another place) is executed and not the greet() of GrandParent.
Or is this possible in the first place?
I don't see how this is possible if you are to have a non-extended Parent object call a different greet method without changing Parent or Grandparent code.
You could write an instance (not static) inner class within RunMe that extends Parent and overrides Parent instance's run() such that it makes a call to the RunMe instance's run(). Your main() method would create an instance of the new subclass instead of Parent.
First, you need an instance of RunMe to invoke its run() method, since that isn't a static method. One way to hook into what's happening in Parent is to subclass Parent:
public static void main(String args[]) {
final RunMe runMe = new RunMe();
Parent p = new Parent() {
public void run() {
super.run(); // runs Parent.run()
runMe.run(); // runs the hook function
}
};
p.run();
}
I have no idea if this is what you're after.
try this:
public class MyParent extends Parent {
#Override
public void greet() {
System.out.println("hello from MyParent");
}
}
public class RunMe {
public static void main(String args[]) {
Parent p = new MyParent();
p.run();
}
}
I think you meant this:
public class RunMe extends Parent {
public static void main(String args[]) {
Parent p = new RunMe();
p.run();
}
public void greet() {
System.out.println("Hi.");
}
}