2013-09-19 3 views
2

У меня есть проблемы с пониманием ниже кода (комментировал против номера строки)не в состоянии понять, наследование и переопределение/перегрузки в Java

class Base { 
    void m1(Object o) { 
    } 

    void m2(String o) { 
    } 
} 

public class Overloading extends Base { 

    void m1(String s) { 
    } 

    void m2(Object o) { 
    } 
public static void main(String[] args) { 
    Object o = new Object(); 
    Base base1 = new Base(); 
    base1.m1("");//**why this works perfect** 
    Base base = new Overloading(); 
    base.m2(o);// **why compile time error** - The method m2(String) in the type Base is not applicable for the arguments (Object) 

ответ

7

Компилятор всегда разрешает вызов метода на основе объявленного типа ссылки вы вызываете его.

При вызове метода:

base1.m1(""); 

компилятор ищет сигнатуры метода в объявленного типа base1, что в этом случае Base. Метод согласования в Base является:

void m1(Object o) { } 

Поскольку параметр Object может принимать String аргумент, вызов является действительным. Вы можете передать объект подкласса в ссылку суперкласса.


Теперь, с 2-го вызова:

base.m2(o); 

вновь объявленный тип base является Base. И метод сопоставления в Base классе:

void m2(String o) { } 

Поскольку вы не можете передать Object ссылки, где String принимаются. Компилятор дает вам ошибку компилятора. Существует неявное сужение конверсии.


Вы можете понять это более ясно с помощью простого задания:

Object ob = new Integer(3); 
String str = ob; // This shouldn't be valid 

Java не выполняет неявное преобразование сужающийся. Назначение от obj до str не должно быть действительным, потому что иначе вы получите ClassCastException во время выполнения.

+0

Можно ли сказать, что поскольку String является подтипом объекта, он работает в первом случае, но поскольку объект не является подтипом String, второй не удается? – Prateek

+0

@Prateek. да, вы можете так сказать. –

+0

@RohitJain можно передать любой тип объекта в первом вызове void m1 (Object o) {}, так как каждый класс расширяет класс Object? –

4

На линии base.m2(o), компилятор не знает, что base является Overloading - это только знает, что это Base. Почему он забыл? Потому что вы сказали .

Вы сказал компилятор для лечения base как Base, объявив его Base base = ....

Таким образом, в соответствии с вашими инструкциями, компилятор будет рассматривать base как Base, ничего не зная ни о каком подклассу Base он может или не может продлить, и (правильно) указывает на то, что base может не поддерживать m2 на произвольном Object.

Смежные вопросы