1
class Movie {
    public void play() {
        System.out.println("playing movie");
    }

}

class DVD extends Movie {
    @Override
    public void play() {
        System.out.println("playing dvd");
    }

    public void menu() {
        System.out.println("showing menu");
    }

}

public class Main {
    public static void main(String[] args) {
        Movie m = new DVD();
        m.play();
        m.menu(); //error
    }
}

From my understanding, m is a DVD object. It prints out "playing DVD" because of that. But why

m.menu()

gives me an error if it's not overridden from the parent class Movie? It's complaining that I don't have menu() method in Movie class.

Also, in which circumstances you would declare some object as

Parent obj = new children();

like this? Do you do this when you want to make sure methods in the child class is overridden from parent? If that's the case why don't you just make the method in the parent class "abstract" or even make the parent as an Interface? My title might be misleading but is this behavior called upcasting? or polymorphism?j

raven39
  • 135
  • 1
  • 7
  • `Movie m = new DVD();` -> `m` is seen as `Movie` and `m.play();` will call the `play()` from `Movie class`. So you need to cast it to `(DVD)m.menu();` or declare `m` like `DVD m = new DVD()`, but you will no longer have access `play()` from `Movie` – KunLun Feb 12 '19 at 22:07
  • Yes, in memory (and thus your program), they are still DVD objects. However by referring to them as a `Movie`, at that point in time you have no way of knowing where to grab a `#menu` method from, it's not in `Movie`'s class definition. You can check if it's a type of a class that _does_ have that method however, and cast/call the method accordingly – Rogue Feb 12 '19 at 22:10
  • You should ask one question per question, or it's harder to answer. :) A good rule of thumb is that if you start a paragraph with "Also," you're probably trying to ask too much in a question. But for that second question, check out https://stackoverflow.com/questions/383947/what-does-it-mean-to-program-to-an-interface – yshavit Feb 12 '19 at 22:13

3 Answers3

4

When you see Movie m = new DVD(), you, the human, know that m is a DVD. But the compiler doesn't know that -- it only knows it's a Movie, since that's all you told it that it should know. So when it sees m.menu(), it looks for that method on Movie and doesn't find it. It doesn't analyze your code to figure out that m is really a subclass of Menu, and specifically DVD, and that that class does have menu(). It only thinks of Movie m, and thus complains that Movie doesn't have a method menu().

This happens all the time in Java, where you might have a line like:

List<Foo> myList = new ArrayList<>();

See "What does it mean to 'program to an interface'?" as to why you might want to do that. But for your question, note in particular that ArrayList defines a method trimToSize() that isn't defined in List. If you declared myList as above, you would not be able to invoke myList.trimToSize().

yshavit
  • 42,327
  • 7
  • 87
  • 124
2

Movie m = new DVD();

keeping child instance at runtime due to runtime polymorphism, But Java is static/structure type programming so it's always maintain it's type strictly so Movie object always finds it's structure attributes. So Movie object m can't find menu() method at run time. so if you want to achieve this you have to do like below

DVD m = new DVD();

or

Object m=new DVD();

((DVD)m).menu();

or

Movie m=new DVD();

DVD d=(DVD)m; m.menu();

But your thinking was correct if Java is dynamic type programming where Duck type used to resolve object structure at runtime.

For more details about type , read from here

Mahamudul Hasan
  • 2,745
  • 2
  • 17
  • 26
1

I hope this helps:

Like people commented, the reasons this gives an error is because m is defined (by you) as a movie. Being in fact a DVD (Which is also a Movie) doesn't contradict that, and so it works.

There are different reasons to store a child object as if it was a parent, for example if you want some unified treatment on the different children that belong to one parent class (e.g. DVD, BluRay, Cassette etc)

You might also want the Movie itself to be functional, and therefore making it abstract is not useful for you (imagine you are designing a game, and you want to have say Orc, but also Uruk-Hai, which are children of Orcs, you'll still want both to be functional by themselves).

Finally, not sure if this is what you are interested in, by look up 'visitor pattern' it might be relevant for what you are asking at the end.

Tacratis
  • 1,035
  • 1
  • 6
  • 16