Contest question: Java code about overwriting methods

4

I took a quiz and dropped the following question:

  

Check the alternative corresponding to the result of executing the main method of the Java program presented below:

public class A {

public void ml(){
    mx();
}

public static void main(String[] args){

    A a = ( B) new C(); 
    a.m1();
    B b = (B) new A(); 
    b.m1();
}

public void mdx(){ 
     System.out.print(10);
}
}


class B extends A{
public void mx(){
    System.out.print(30);
}
}

class C extends B {
public void mx(){
    System.out.print(40);
}
}
     

(a) The value 40 and the value 10 shall be printed.   b) The value 40 and the value 30 shall be printed.   c) The value 10 and the value 10 shall be printed   d) The value 40 will be printed and later the ClassCastException exception will be released.   e) The value 10 will be printed and later the ClassCastException
will be thrown

Note: I saw that there is a blank space in: ( B)

The template says that the correct one is the letter D, but I am in doubt on this question. Is this template correct? If yes, why? And if not, also, why?

    
asked by anonymous 02.02.2017 / 10:47

2 answers

14

There are compilation errors in this code:

  • Within method ml() of A , method mx() invoked does not exist in class A . I think it was for the method mdx to be called mx .

  • No main is invoking a method called m1 , not ml . I think it was for these names to be the same.

See this not working on ideone:

Main.java:4: error: cannot find symbol
    mx();
    ^
  symbol:   method mx()
  location: class A
Main.java:10: error: cannot find symbol
    a.m1();
     ^
  symbol:   method m1()
  location: variable a of type A
Main.java:12: error: cannot find symbol
    b.m1();
     ^
  symbol:   method m1()
  location: variable b of type B
3 errors

Note: This Main.java is because I'm compiling in ideone (and I had to get the public from the A statement), that's just an ideone limitation. If you are compiling yourself, it will show A.java instead of Main.java .

Correcting these compilation errors, 40 is displayed and then ClassCastException is posted, just as alternative D is.

On the A a = ( B) new C(); line, the cast is valid because even though C is being instantiated, we have C extends B , so the cast for B is valid. In addition, a reference to B can be assigned to a variable of type A because B extends A .

The fact of having a space inside the cast is irrelevant, because the process of tokenization of the compiler (what chucks the source code in tokens), will separate the cast in three tokens: The open parentheses, the type of cast (% with%) and the parenthesis. Spaces do not interfere with this process.

The call to B will call the a.m1() method of the object that is in the m1 reference. This object is that of a , so it is of type new C() . The C class overwrites the C inherited method from m1 and B . So, what is going to be executed is the A method of class m1 , which prints 40.

In the line C , we have that it is not true that B b = (B) new A(); , soon this will give a A extends B . The compiler allows this because the result of the ClassCastException subexpression is of type new A() . A cast from A to A is allowed by the compiler because there is inheritance relation between these classes.

See here working on ideone. In this code, I made the suggested fixes at the beginning and added B within try-catch so that it can show the exception properly.

    
02.02.2017 / 11:22
2

If in class A in

public void m1()
{
    mx();
}

was

public void m1()
{
    mdx();
}

So the letter and would be the right answer.

But if in class A, if the mdx method, if you called it instead, mx , then the d right answer.

But the way the answer is currently typed is "Do not compile" because mx does not exist in class A. No matter if there is mx in the children, the method search is always done on the current object and on the parents, never on the children .

Here is the code for class A that would make the letter " d " be the correct one:

package testes;

public class A 
{
    public void m1()
    {
        mx();
    }

    public static void main(String[] args)
    {
        A a = ( B) new C(); 
        a.m1();

        B b = (B) new A(); 
        b.m1();

    }

    public void mx()
    { 
         System.out.print(10);
    }
}

What do you learn by analyzing this exercise specifically in the section below?

        A a = ( B) new C(); 
        a.m1();

It is learned that the method that will be executed is always the one of the object in question, that is, the last one that overwritten the method, in this case it was that of the object C. If this method did not exist in the object in question, it would try to call the father's, which is B, and if there was no method in the father, would try to call the grandfather, who is A, going up the hierarchy until he found the method. Since m1 exists in C, it executes this and not the others.

Remember that the object is created when you use the word new . C was stored as a B and B was stored as an A, but in essence it remains C. This is to allow the Polymorphism, follow an example below taken from DevMedia:

abstract class Mamífero {
    public abstract double obterCotaDiariaDeLeite();
}

class Elefante extends Mamífero {
    public double obterCotaDiariaDeLeite(){
        return 20.0;
    }
}

class Rato extends Mamifero {
    public double obterCotaDiariaDeLeite() {
        return 0.5;
    }
}

class Aplicativo {
    public static void main(String args[]){
        System.out.println("Polimorfismo\n");
        Mamifero mamifero1 = new Elefante();
        System.out.println("Cota diaria de leite do elefante: " + mamifero1.obterCotaDiariaDeLeite());
        Mamifero mamifero2 = new Rato();
        System.out.println("Cota diaria de leite do rato: " + mamifero2.obterCotaDiariaDeLeite());
    }
}

Reference: Article in DevMedia: Encapsulation, Polymorphism, Inheritance in Java

    
02.02.2017 / 15:12