2015-03-15 3 views
0

Почему я не могу получить доступ к методу внутри класса Daily из основного, расположенного в классе Test. В частности метод incomingOn() - это тот, который я хотел бы получить в форме main. Если я создам объект из типа Daily, то он позволяет мне получить доступ к методу replaceOn(), но если я изначально объявляю его как общее назначение, то это не так.Изучение полиморфизма

Я пытаюсь научить себя полиморфизму кстати.

public class Appointment{ 

private String description; 
private String date; 

public Appointment(){ 
    this.description = ""; 
    this.date = ""; 
} 
public Appointment(String de, String da){ 
    this.description = de; 
    this.date = da; 
} 

public void setDescription(String d){ 
    this.description = d; 
} 
public String getDescription(){ 
    return this.description; 
} 
public void setDate(String d){ 
    this.date = d; 
} 
public String getDate(){ 
    return this.date; 
} 

public String toString() { 
    return "Appointment [description=" + description + ", date=" + date + "]"; 
} 
} 

public class Daily extends Appointment{ 

public Daily(){ 
    super(); 
} 
public Daily(String de, String da){ 
    super(de, da); 
} 

public boolean occursOn(int year, int month, int day){ 
    return true; 
} 
public String toString(){ 
    String str = "Daily " + super.toString(); 
    return str; 
} 
} 

public class Test { 

public static void main(String [] args){ 

    Appointment appt1; 

    appt1 = new Onetime("See doctor", "01/01/2015"); 

} 
} 

ответ

3

Это потому, что дочерние классы наследуют атрибуты родительских классов, а не наоборот. Хотя вы можете обобщить экземпляр «Ежедневно» на «Назначение», вы теряете возможность вызывать суточные методы на экземпляре без приведения.

Если вы хотите получить доступ к вызовуOn() как в Daily, так и в Appointment, вам необходимо объявить метод в классе Appointment, чтобы он был унаследован его подклассами.

+0

Спасибо, это имеет большой смысл. –

2

Назначение не имеет occursOn().

Если у вас есть maleDuck extends duck, и вы даете мне один, но только скажите мне, что это утка, я могу сделать это quack(), но я не знаю, если это layseggs().

Duck ladyDuck = new FemaleDuck(); 
ladyDuck.layseggs(); //WRONG, not a ducks lay eggs 

FemaleDuck ladyDuck = new FemaleDuck(); 
ladyDuck.layseggs(); //CORRECT, it's clear we're dealing with female ducks 

Что интересно полиморфизм, когда мы overload в quack() (псевдо-коде:) ...

Duck[] ducks = { new MaleDuck(), new FemaleDuck() }; 
foreach (duck in ducks) { duck.quack() }; 
Assert("1 manish quack and 1 ladyish quack just happened"); 

... мы можем относиться к ним одинаково и получить доступ к своему уникальному поведению. Но мы не можем просто называть layegg() членам этого массива, потому что MaleDucks будет бороться.

Ознакомьтесь с некоторыми tutorials о полиморфизме.

Я не знаю, почему я не поставил это с точки зрения назначений. Но я считаю, что просто неписаный закон, что все примеры полиморфизма должны быть объяснены с точки зрения любых автомобилей или животных. : D

+0

Большое вам спасибо. Он тоже немного потрудился, и мне пришлось обновить мою память о наследовании, но я понял. –

1

Ваш класс Appointment должен иметь метод. Он не нужно заполнять. , то вы можете переопределить его в классах, которые переопределяют назначение.

1

Если объявить Daily как Appointment, вы должны выполнить обратное приведение переменной к ее надлежащего типа для того, чтобы получить доступ к Daily «s occursOn метод:

Appointment appt1; 
appt1 = new Daily("See Doctor", "01/01/2015"); 
((Daily) appt).occursOn(); 

Если тип объявлен как Appointment, то компилятор знает только о методах Appointment, даже если базовый тип - Daily. «Downcasting» - это процесс, с помощью которого вы уточняете тип ссылки на один из его производных классов. Обратите внимание, что вы можете только опущенными к производному типу, когда основной класс фактически производного типа, например, если вы попытаетесь это сделать:

Appointment appt1; 
appt1 = new Appointment("See Doctor"); 
((Daily) appt).occursOn(); //Compiler throws an error!! 

Вы в конечном итоге в мире вреда.

+0

Хотя это правда. Я бы не рекомендовал нисходящее литье. Если вы хотите 'Daily' и собираетесь делать« Daily »вещи, просто попросите' Daily' –

+0

Определенно верно, хотя он служит хорошим примером того, что на самом деле происходит, когда вы передаете 'Daily' объект в функцию, которая принимает объект «Назначение». Это полиморфизм на работе. Объект сохраняет свою базовую идентификацию при передаче для родительского типа. – kellanburket