How do I access Super class variables and methods in main method? - java

class Main
{
public static void main(String[] arg)
{
C c = new C();
c.show(); //how to access class A
}
}
class A
{
void show()
{
System.out.println("inside A");
}
}
class B extends A
{
void show()
{
System.out.println("inside B");
}
}
class C extends B
{
void show()
{
super.show(); //How to access class A
System.out.println("inside C");
}
}
Using super I can access Super Class variables and methods like C can access B's methods but what if I want to access A's methods in C. How do I do that in simple way like using super? Like two super should do the trick...
And how do I access Class A method only by allocating Class C(if name-hiding present)?

There is no construct in Java to do something like c.super.super.show() as it violates encapsulation. The Law of Demeter is a good principle illustrating why this is rightly avoided. Taking this into account, the way you can do what you request within Java is to expose a.show() in b like this:
class Main
{
public static void main(String[] arg)
{
C c = new C();
c.show(); //how to access class A
}
}
class A
{
void show()
{
System.out.println("inside A");
}
}
class B extends A
{
void show()
{
System.out.println("inside B");
}
void showA()
{
super.show();
}
}
class C extends B
{
void show()
{
super.showA(); // Calls A
System.out.println("inside C");
}
}

One way of using A's show() method in C is by creating class A object in C and using A's show function.
class C extends B
{
void show()
{
new A().show();
super.show();
System.out.println("inside C");
}
}

Related

How to invoke the method in abstract class that has been overriden in the subclass in java?

In this below code:
interface I1 {
void m1();
}
interface I2 {
void m2();
}
abstract class A implements I1, I2 {
public void m1() {
System.out.println("Inside A: m1()");
}
}
class B extends A {
public void m1() {
System.out.println("Inside B: m1()");
}
public void m2() {
System.out.println("Inside B: m2()");
}
}
public class Test {
public static void main(String[] args) {
// invoke A's m1()
A a = new B();
a.m1();
}
}
How can I just invoke m1() in A without making any changes to class B i.e. we can't add super.m1() in the m1() in B? With my code I just get the m1() in B because of dynamic method dispatch or runtime polymorphism.
An interviewer asked me this question. And I told him that it wasn't possible to do so but he replied that there is a way but didn't told me how.

Call method using type variable generics

I have a scenario that i want to create one support class called D which contains a generic method. I have set the upper bound for type variable.
class A{
void show(){
System.out.println("Hello A");
}
}
class B extends A{
void msg(){
System.out.println("Hello B");
}
}
class C extends A{
void msg(){
System.out.println("Hello C");
}
}
class D{
<T extends A> void display(T ob){
ob.msg(); //here i want to do some tricks
}
}
First i want to share my objective. Here msg() function of B and C class has different implementations. I want to create one support class called D that has one display method, using display method i want to call either msg() function of B or C class dependent on instantiation. Can you tell me how can i achieve it?
You need to have the method msg() in class A, otherwise the display() method in class D does not know if this method exist or not in the object that you're passing to it. (What if someone makes a class E that extends A but does not have a msg() method, and you pass an E to D.display()?).
If you don't want to implement the msg() method in class A, then you can make it abstract (and you'll also have to make the class abstract).
abstract class A {
public abstract void msg();
// ...
}
more like an architecture style, I would use an interface for that, so your generic method constrains to <T extends If> void display(T ob) where If is the interface with the abstract method msg
interface If {
void msg();
}
class A {
void show() {
System.out.println("Hello A");
}
}
class B extends A implements If {
#Override
public void msg() {
System.out.println("Hello B");
}
}
class C extends A implements If {
#Override
public void msg() {
System.out.println("Hello C");
}
}
class D {
<T extends If> void display(T ob) {
ob.msg(); // here i want to do some tricks
}
}
You don't need generics for this, there is basic concept called dynamic binding in Java.
abstract class A{
void show(){
System.out.println("Hello A");
}
abstract void msg();
}
class B extends A{
#Override
void msg(){
System.out.println("Hello B");
}
}
class C extends A{
#Override
void msg(){
System.out.println("Hello C");
}
}
class D{
void display(A ob){
ob.msg();
}
}
Here an appropriate instance provided to method will determine which class method should in called at runtime.

In Java is it possible to check at runtime on which subclass a method was called?

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");
}
}

extending inner clsses in java

public class Questions {
public static void main(String[] args) {
D d = new D();
}
}
class A {
A() {
System.out.println("A");
}
}
class B extends A {
B() {
System.out.println("B");
}
class C {
C() {
System.out.println("C");
}
}
}
class D extends B.C {
D() {//compilation error
System.out.println("D");
}
}
This shows an error while D is created that some intermediate constructor call. please tell me how do I extend such inner classes and what is wrong with this code.
Thank you.
You have to make the class C static so that it can be accessed from outside B.
class B extends A {
B () {
System.out.println("B");
}
static class C {
C () {
System.out.println("C");
}
}
}
Apart from a theoretical question, why would you do this?
All non-static inner classes need to have reference to instance of its outer class. If you want to extend such class you need to assure that object which will be used as base will have instance of its outer object. So you can do something like this:
class D extends B.C {
D(B b) {
b.super();
System.out.println("D");
}
}
and use
D d = new D(new B());

Overriding method with composition

Consider following situation. I want to achieve the different behavior for methoddA() of class A depending upon from where it is getting call like here from class D or class C. How this can be achieved, method overriding is not working here.
class A
{
public methodA(){ //some code }
}
class B
{
A a = new A()
public methodB()
{
a.methodA();
}
}
class C
{
B b = new B();
public methodC()
{
b.methodB();
}
}
class D
{
B b = new B();
public methodD()
{
b.methodB();
}
}
What you need here is Polymorphism. First create an interface -
public interface MyInterface
{
void methodA();
}
then create two different implementations for two different behaviors -
public class First implements MyInterface
{
public void methodA() {
// first behavior
}
}
public class Second implements MyInterface
{
public void methodA() {
// second behavior
}
}
Now create your other classes as follows -
class B
{
public void methodB(MyInterface m)
{
m.methodA();
}
}
class C
{
B b = new B();
public void methodC()
{
// Pass the corresponding behavior implementation
// as argument here.
b.methodB(new First());
}
}
class D
{
B b = new B();
public void methodD()
{
// Pass the second behavior implementation.
b.methodB(new Second());
}
}
This will result in a more maintainable code.
You can pass the class name to your method as a String and in your method check
if(className.equals("A") // or use isInstanceOf() if you are passing objects of A/B
//do something
if(className.equals("B")
// do something else.
Why do you need two different implementations?
This easy trick can work for you... Please correct me if i am wrong..
I following code I have modified the method signature of Class A1 and Class B1 to accept Object and similarly while calling the methods from Class C and Class D whereever we are calling this method of class B1 pass this as reference. In Class A1 we can then check instanceof object and identify the calling class.
class A1
{
public void methodA(Object c){ //some code }
if (D.class.isInstance(c)){
System.out.println("Called from Class D");
}else if (C.class.isInstance(c)){
System.out.println("Called from Class c");
}else{
System.out.println("Called from Some diff class");
}
}
}
class B1
{
A1 a = new A1();
public void methodB(Object c)
{
a.methodA(c);
}
}
class C
{
B1 b = new B1();
public void methodC()
{
b.methodB(this);
}
}
class D
{
B1 b = new B1();
public void methodD()
{
b.methodB(this);
}
}
public class Testnew{
public static void main(String args[]){
D d = new D();
d.methodD();
C c = new C();
c.methodC();
B1 b = new B1();
b.methodB(b);
}
}

Categories