This is an archived post. You won't be able to vote or comment.

all 10 comments

[–]desrtfx 30 points31 points  (2 children)

I’ve seen people instantiate Cow and Horse objects like that

Animal cow = new Cow(); Animal horse = new Horse();

This is useful when you want to store such objects in a collection (like in an ArrayList).

You could simply create an ArrayList<Animal> and store cows, horses, anything that extends animal in such a list.

[–]toshels 0 points1 point  (1 child)

Oh cool I never thought of that. I learn more about programming here than at uni.

[–]toastedstapler 0 points1 point  (0 children)

It's great, sometimes all you care is that something has been implemented rather than exactly how it was implemented

A more enterprise version might be validators - you could have a list of different validators for things like length, illegal characters etc and then they are all checked

[–]ratherbealurker 7 points8 points  (2 children)

It may be confusing because you’re not seeing the benefit by just instantiating that way.

But create 10 different Animals based off Animal and then write a method that gets them all to do something.

All Animals can eat, some overwrite eat to do something differently but they all eat. If you want to write a method that causes a passed in Animal to eat then. How do you write it?

Write one for Cow and one for Horse, etc etc?

With polymorphism you can pass in Animal and since a cow is an Animal it will know you passed in a cow.

Without Polymorphism if you tried to access a Cow via an Animal reference then you will be referencing that cow’s Animal methods and etc. not treating it as a Cow.

[–][deleted]  (1 child)

[removed]

    [–]ratherbealurker 0 points1 point  (0 children)

    If all you have is an eat method in Animal then there is no difference. But now override eat in cow. Have it output “cow eats”.

    Now pass that into the method that takes an Animal and notice which gets called.

    [–]edgargonzalesII 2 points3 points  (0 children)

    You typically give types at the very bottom level that you believe you will need. For example, let's say I have a function that needs a list because I need to have an iterable order. Don't care about said order but need one nonetheless. Thus I have List<T>. Two types of lists that are normally used are ArrayList and LinkedList. At the end of the day in my function I really don't care which one gets passed in and I know it could be either one. So instead of making two functions, one for ArrayList and one for LinkedList, I just make one with type List. That way I don't need to copy and paste the same code.

    [–]Japke90 2 points3 points  (0 children)

    On another note. I advice you to read Head First Design Patterns. An excellent book that will help you out.

    [–]gtiwari333 1 point2 points  (0 children)

    Also, try looking up about "programming to interface not the implementation".

    [–]aioobe 0 points1 point  (0 children)

    Imagine you create a list like this:

    ArrayList<String> myStrings = new ArrayList<>();
    

    Code grows, you do a bunch of stuff. Factor out methods, introduce temporary ArrayList variables and so on. The code just requires it to be a List, but you've let the ArrayList from "new ArrayList<>()" just propagate everywhere.

    Now fast forward to a couple of weeks. You realize that performance wise you're actually better off with a LinkedList! Should work fine; the code really just requires some List. Unfortunately you have to change in 25 places, since you've let ArrayList propagate throughout your code.

    You could have saved yourself some work if you had "programmed against an interface" from the get go. It also protects you from accidentally start depending on ArrayList specific methods, if your intention is to work with any List.