Domanda

So this is pretty basic but I can't get a hold of it. Let us assume we have 2 classes A,B (inherits from A):

  class A {
        public void m() {System.out.println("AAA");}
    }
  class B extends A {
        public void m() {System.out.println("BBB"); }
    }

Our main class:

class Test{
    public static void main(String [] args){
        A a=new A(); B b=new B(); A x;
        x=a; x.m(); // "AAA"
        x=b; x.m(); // "BBB"

        a=b; a.m();   // "BBB"
        b=a; b.m();   // ERROR
    }}

In my understanding 'x' is a reference to null of type A, because no object was created. When I type x=a; the reference to null now points to the instance of A. If I call x.m() it prints "AAA" ..same with x=b; x.n(); "BBB";

BUT if I create an instance A where 'a' is the reference to and say b=a; it says error. Found A required B.

Well I thought reference of 'b' is overwritten with the reference 'a' and if I now call b.m(); it gives me the "AAA" because it now points to the instance of A. Though a=b; with a.m() prints "BBB"

Why??

È stato utile?

Soluzione

Firstly I'm just adding some characters to your class names:

  class Animal {
        public void m() {System.out.println("AAA");}
  }
  class Bee extends Animal {
        public void m() {System.out.println("BBB"); }
  }

class Test{
public static void main(String [] args){
    Animal a=new Animal();
    Bee b=new Bee();
    Animal x;

    x=a; x.m(); // "AAA" a is an animal
    x=b; x.m(); // "BBB" b is a Bee, so it's an Animal

    a=b; a.m();   // "BBB" A Bee is an Animal
    b=a; b.m();   // ERROR An Animal is a Bee? What if it's a Cat?
}}

In case is still not clear, let's create the class:

class Cat extends Animal{
    public void m() {System.out.println("CAT"); }
    public void foo() {System.out.println("FOO"); }
};

You could change in the previous code Animal a=new Animal(); by Animal a= new Cat(); and then you'll see b=a is incorrect because a Bee is not a Cat.

UPDATE: I added two methods to the class Cat. Let's see how it works:

// This is the obvious part:
Cat c= new Cat();
c.m(); // "CAT"
c.foo(); // "FOO"

// Not so obvious
Animal a2= new Cat(); // a Cat is an animal
a2.m(); // "CAT"
a2.foo(); //Won't compile: ERROR

What happens here? Cat is an animal, and this ensures it has the method m. The behavior of the method is defined by the instance itself. a2 is a variable that points at a Cat instance, but we can only call the methods defined by Animal because a2 could also be any other animal and we don't know which methods it could have. Yes, it this case we know it's a cat, but let's say we have this method:

public Animal createAnAnimal() {
    if (Random.nextBoolean()) {
        return new Cat();
    } else {
        return new Bee();
    }
}

Anyway, you should read about inheritance and interfaces, which add more complexity to this stuff.

Altri suggerimenti

I think your problem is, that you have a wrong point of view.

You think, if you're setting a = b, then a will be of type B! But it is not. a is still of type A and has a reference to an instance of class B.

So that's why you can't set a value of class A to a variable of type B!

A a = new A();
B b = new B();
A x;

x = a; // x is of type A and has now a reference to an instance of type A
x = b; // x is of type A and has now a reference to an instance of type B

a = b; // a is of type A and has now a reference to an instance of type B
b = a; // b is of type B and you can't set a reference to a variable of type A

Imagine you have another class C:

class C extends A {
   public void m() {System.out.println("CCC"); }
}

Then your code could be modified:

A c = new C();
B b = c;

This obviously isn't correct, hence the error.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top