Down Casting to indirect subclass does not work? - java

public class A
{
public void printA(){
System.out.println("A");
}
}
public class B extends A
{
public void printB(){
System.out.println("B");
}
}
public class C extends B
{
public void printC(){
System.out.println("C");
}
}
public class test {
public static void main(String[] args)
{
A a = new B();
a.printA(); // work
B b = (B) a;
b.printB(); // work
C c = (C) b;
c.printC(); // not work throw java.lang.ClassCastException
}
}
i have three classes A and B and C
C extends from B and B extends from A
why down casting work from A to B, and does not work from B to C ,although the relation between them like A and B , B is parent of C so how it work JVM??

Classes can only be cast to their parent classes, they have no knowledge about their subclasses.
Since your object is an instance of B, it does not implement methods of C.
This will work:
A a = new C();
a.printA(); // work
B b = (B) a;
b.printB(); // work
C c = (C) b;
c.printC(); // work

Related

Avoiding Dynamic Type Casting with Inheritance for Data Classes in Java

I have 3 Data Classes
#Data
class A
{
private int a;
}
#Data
class B extends A
{
private int b;
}
#Data
class C extends A
{
private int c;
}
Class B and C have some common fields between them which is kept in their parent class A.
Following is the tester class
class TesterClass
{
static String bOrC = "C"; // input from some decision
public static void main(String[] args) // assume this to be the client
{
A a;
if (bOrC.equals("B")) {
B b = new B();
b.setB(11);
a = b;
} else {
C c = new C();
c.setC(12);
a = c;
}
a.setA(10);
doSomething(bOrC, a);
}
// Below are the service methods
// only this method in the service exposed
public static void doSomething(String bOrC, A a) {
if (bOrC.equals("B")) {
doSomethingWithB(a);
} else if (bOrC.equals("C")) {
doSomethingWithC(a);
}
}
public static void doSomethingWithB(A a) {
B b = (B) a; // possible ClassCastException
System.out.println(b.getA());
System.out.println(b.getB());
}
public static void doSomethingWithC(A a) {
C c = (C) a; // possible ClassCastException
System.out.println(c.getA());
System.out.println(c.getC());
}
}
Now the problem I see with this is unsafe Dynamic Type Casting which can run into Class Cast Problems. One possible solution would be to create separate data objects and set the common fields (which are too many for my actual case) for both the objects separately in both classes B and C which would then look as follows:
public class TesterClass
{
static String bOrC = "C"; // input from some decision
public static void main(String[] args)
{
if (bOrC.equals("B")) {
B b = new B();
b.setA(10); // duplication
b.setB(11);
doSomethingWithB(b);
} else {
C c = new C();
c.setA(10); // duplication
c.setC(12);
doSomethingWithC(c);
}
}
public static void doSomethingWithB(B b) {
System.out.println(b.getA());
System.out.println(b.getB());
}
public static void doSomethingWithC(C c) {
System.out.println(c.getA());
System.out.println(c.getC());
}
}
I'm looking for a way to avoid this dynamic type casting but at the same time avoid having to duplicate the common variables. Can anyone suggest a solution?
Abstraction is one solution for the behavior you are explaining. Creating an abstract method doSomething(...) in class A and implementing it in child class B and C respectively. By doing this you don't need to have a static method and processing will be done bases on the instance of B or C objects itself.
#Data
class A
{
private int a;
public abstract void doSomething();
}
#Data
class B extends A
{
private int b;
public void doSomething(){
/*.... do something here
* here you can also access parent public methods and properties.
* as you have already annotated with #Data you will have access to getA() method, * hence you can also use parent properties.
*/
}
}
#Data
class C extends A
{
private int c;
public void doSomething(){
/*.... do something here
* here you can also access parent public methods and properties.
* as you have already annotated with #Data you will have access to
* getA() method, * hence you can also use parent properties.
*/
}
Now you can use it as below
public static void main(Strings[] args){
A a;
B b = new B();
b.setB(10);
b.doSomething();
C c = new C();
c.setC(30);
c.doSomething();
}

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

Creating instance of member variables

Hi this is a basic question, but kindly bear with me.
I have two classes and on class has a reference of another class. How can i create the instance of second class which is present in first class at the time creation of instance of first class. Are any utility present for this.
Code ::
class A {
B b;
}
class B {
int member;
}
In a Contructor (like Robert Kock already said)
class A {
B b;
public A(){
b = new B();
b.member = 5;
}
}
Directly as Attribute
class A {
B b = new B(5);
}
With Initializer
class A {
B b;
{
b = new B();
b.member = 5;
}
}
Within the constructor of the first class:
class A
{
public A()
{
b = new B();
}
B b;
}
Or even like this:
class A
{
public A()
{
}
B b = new B();
}
A general solution would be:
public class A {
private final B b;
public A(B b) {
this.b = b;
}
}
...
A a = new A(new B());
It becomes interesting when both instances refer to each other, then you need to use a setter in at least one of the classes:
public class B {
private A a; // the field cannot be final in this case
public void setA(A a) {
this.a = a;
}
}
....
B b = new B()
A a = new A(b);
b.setA(a);
The answers where the class is creating the other instance itself are not a general solution.

How come the Up-casting for c is redundant?

I am trying to figure out why the casting is redundant(thats the warning I get) in the end whats printed is "C".
public class Main {
public static void main(String[] args){
C c = new C();
B b1 = (B) c;
b1.f();
}
}
class A{
void f(){
System.out.println("A");
}
}
class B extends A{
}
class C extends B{
void f(){
System.out.println("C");
}
}
C extends B means that C is a B. And you do not need to cast C to B, because it IS a B.
So upcast (C to B) is always redundant. The only case when you would need cast is downcast (B to C):
B b = new C();
C c = (C) b;
Class c extends class B. So any C object is also a B object because of inheritance. So you do not need to explicitly cast '(B)' before c.

how to access an instance of a class from its instance variable

So I have this scenario
class A:
public class A {
B b = new B();
public void doSomething() {
// this does something
}
}
and class B:
public class B {
public B() {
// need to access A
}
}
The problem is that I need to access the instance of A from the A's instance variable B. How do I do that?
You may simply pass the instance of A to B:
class A {
B b;
A() {
b = new B(this);//<-- A's instance
}
}
class B {
A a;
B(A a) {
this.a = a;
}
}
If class Bneeds to access an existing instance of A then you must provide the B instance with a reference to the A instance.
class B {
private A a;
B(A a) {
this.a = a;
// do something with a
}
}
then
A a = new A();
B b = new B(a);
If you need access to the A only within the constructor then you don't need to store a local copy of the reference.
You must create new object from instance A
A aa = new A();
OR
public class B extends A {
public B() {
// need to access A
}
}
Inner Class seems like the best thing to do ,
public class A {
B b = new B();
private int tryToAccess;
public void doSomething() {
// this does something
}
public class B{
public B()
{
tryToAccess=5;
}
}//B ends
}//A ends
Note:This is just one way of going about it , here you can access A's private variables from class B

Categories