Search code examples
jdbccastinginversion-of-controldao

IOC/JDBC/DAO - How does this code example work?


I have hard time understanding this code. Phone13 is the parent interface for both SamSung and HTC classes. And VO is the parent Class for both SamSungVO and HTCVO. Now, I create a SamSung instance for my interface myPhone13. Then, I create a SamSungVO instance. I also cast it to VO and put it into myPhone.info(myVO) method.

I can't understand that although myPhone.info(VO myVO) take VO as it's parameter, I've implemented myPhone interface with SamSung Class. So it looks like that I put a VO object into a method that intends to take SamSung object as its parameter. I start to wonder. How could this instance transfers from VO to SamSungVO automatically?

I thought it's not allowed to put a parent object as argument for method that takes child instance as its parameter.

package others;

class VO{}

interface Phone13 <E extends VO>{
    public void info(E myVO);
}

class SamSung implements Phone13<SamSungVO>{
    @Override
    public void info(SamSungVO myVO) {
        System.out.println(myVO.name);      
    }
}
class SamSungVO extends VO{
    String name = "SamSung";
}


class HTC implements Phone13<HTCVO>{

    @Override
    public void info(HTCVO myVO) {
        System.out.println(myVO.name);      
    }

}
class HTCVO extends VO{
    String name = "HTC";
}

public class MyIOC02 {

    public static void main(String[] args) {
        Phone13 myPhone = null;
        // When I need to use SamSung
        myPhone = new SamSung();
        VO myVO = new SamSungVO();
        myPhone.info(myVO);

    }
}

Solution

  • Your myPhone variable is not typed. The compiler gives you a warning at the line

    Phone13 myPhone = null
    

    "Phone13 is a raw type. References to generic type Phone13 should be parameterized".

    Another warning is at the line:

    myPhone.info(myVO)
    

    "The method info(VO) belongs to the raw type Phone13. References to generic type Phone13 should be parameterized".

    If you instantiate the myVO with the HTC type the compiler gives you the same warning, but at runtime there is a ClassCastException.

    myVO = new HTCVO()
    myPhone.info(myVO)
    

    Since you instantiated the myVO to be a SamSungVO in each case the info() method of the SamSungVO derivation is called. If the argument is indeed the expected type, the program runs, if it is the other type, it does not fit and throws.

    The generics is a technology to help the compiler detect type safty. If it can't determine the type safety it give you a warning. You should really obey and solve such compiler warnings, otherwise it's useless to use generics.