Subtypes of Arrays - java

If I have class A { and class B extends A { will
B[] b = new B[1];
b[0] = new B();
System.out.println(b instanceof A[]);
print out true or false?

The JLS states that if B is assignable to A, then yes, B[] is assignable to A[].
This opens the door to serious implications though, demonstrated by this code:
class A {}
class B extends A {}
class C extends A {}
//...
B[] bs = new B[2];
A[] as = bs;
as[0] = new C(); //runtime error
B b = bs[0];
This code compiles but fails at runtime. We call that a lack of type safety.

// A.java
public class A {}
// B.java
public class B extends A {}
// Test.java
public class Test {
public static void main(String[] args) {
B[] b = new B[1];
b[0] = new B();
System.out.println(b instanceof A[]);
}
}
When run:
> javac *.java && java Test
true

It will print true.

false.
Arrays don't follow the same rules as normal Objects.

Related

Associate one and only one object

Hello I have one question.
I have Class A and Class B. I create one object A and multiple objects B. But I want only one B can set with A.
e.x
class A{}
class B{ private A a;}
public static void main(String[] args){
A a= new A();
B b= new B();
B c= new B();
b.setA(a);
c.setA(a);//Sould not assign it.
}
Here is one way to implement such a concept.
Code
class A {}
public class B
{
private static final HashSet<A> setA = new HashSet<>();
private A a;
public void setA(A a)
{
if (!setA.contains(a))
{
this.a = a;
setA.add(a);
}
}
public A getA() { return a; }
public static void main(String[] args)
{
A a0 = new A();
A a1 = new A();
B b0 = new B();
B b1 = new B();
B b2 = new B();
b0.setA(a0);
b1.setA(a1);
// Below two operations fail silently
b2.setA(a0);
b2.setA(a1);
System.out.println(b0.getA());
System.out.println(b1.getA());
System.out.println(b2.getA());
}
}
You can even throw a custom exception instead of failing silently.
Output
george_17092021_1434.A#568db2f2
george_17092021_1434.A#378bf509
null
Conclusion
Doing so should help in achieving what you want. However, I do not know if this is something to be used professionally or not. Please comment if you face any problems.

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.

Down Casting to indirect subclass does not work?

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

Categories