extending inner clsses in java - 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());

Related

Subclass method have weaker access specifier. But i can override. How did this happen?

Why output of this code is class A? Because there is rule subclass overridden method can not have a weaker access specifier. For this rule i think output is must be class B. Please explain why output is class A?
public class B {
public void foo(){
System.out.println("class B");
}
}
public class A extends B{
protected void foo(){
System.out.println("class A");
}
public static void main(String[] args) {
B b = new A();
b.foo();
//output class A
}
}

How does inheritance work in this bit of code?

So guys I've been playing around with inheritance and I've stumbled upon this program :
public class HelloWorld {
static class A {
void f() { System.out.println("A"); }
}
static class B extends A {
void f() { System.out.println("B"); }
}
static class C {
void func(B b) { b.f(); }
}
static class D extends C {
void func(A a){ a.f(); }
}
public static void main(String args[]) {
( (new D())).func( (A) (new B()));
A a = new B();
a.f();
B b = new B();
C c = new D();
c.func(b);
}
}
So how come even though A and C are implemented exactly the same way in the final few lines, A's methods
get overriden by B, but C's don't get overriden by D?
The program prints as follows :
B
B
B
Because Class D function definition is more general than C. C's function takes B type parameter but D function takes type A parameter which is a parent of B. It is more general than a function defined in C.
static class D extends C {
void func(A a){
a.f();
}
}
B b = new B();
C c = new D();
c.func(b);
Variable c is pointing to D's object so c.func(b) invokes method defined in D. A is a parent of B hence B's method is called. Same as it is called using A's reference as shown below.
A a = new B();
a.f();
It is because the method func in D does not override the same of C as the signature change.
static class C {
void func(B b) { b.f(); }
}
static class D extends C {
void func(B a){ a.f(); }
}
This will result in an override of the method

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

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

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

StackOverFlow Error in Instantiating an Object

I'm reviewing for a certification exam and I experimented with the following codes:
class A {
B b = new B();
static {
System.out.println("A static.");
}
{
System.out.println("A instance.");
}
A() {
System.out.println("A constructor.");
}
}
class B extends A {
static {
System.out.println("B static.");
}
{
System.out.println("B instance.");
}
B() {
System.out.println("B constructor.");
}
}
public class Raaawrrr {
public static void main(String args[]) {
A a = new A();
}
}
It prints:
A static.
B static.
and causes a stack overflow afterwards. I'm having a hard time understanding why. Would you be able to help me out?
A instantiates B. B happens to also be of type A, so that gets instantiated again. Which instantiates B... and so forth.
You are creating an object of class B which is sub-class of A in class A. Note that the constructor of super-classes must be executed before the execution of sub-class constructor.

Categories