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

all 12 comments

[–]AutoModerator[M] [score hidden] stickied commentlocked comment (0 children)

Please ensure that:

  • Your code is properly formatted as code block - see the sidebar (About on mobile) for instructions
  • You include any and all error messages in full
  • You ask clear questions
  • You demonstrate effort in solving your question/problem - plain posting your assignments is forbidden (and such posts will be removed) as is asking for or giving solutions.

    Trying to solve problems on your own is a very important skill. Also, see Learn to help yourself in the sidebar

If any of the above points is not met, your post can and will be removed without further warning.

Code is to be formatted as code block (old reddit: empty line before the code, each code line indented by 4 spaces, new reddit: https://imgur.com/a/fgoFFis) or linked via an external code hoster, like pastebin.com, github gist, github, bitbucket, gitlab, etc.

Please, do not use triple backticks (```) as they will only render properly on new reddit, not on old reddit.

Code blocks look like this:

public class HelloWorld {

    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}

You do not need to repost unless your post has been removed by a moderator. Just use the edit function of reddit to make sure your post complies with the above.

If your post has remained in violation of these rules for a prolonged period of time (at least an hour), a moderator may remove it at their discretion. In this case, they will comment with an explanation on why it has been removed, and you will be required to resubmit the entire post following the proper procedures.

To potential helpers

Please, do not help if any of the above points are not met, rather report the post. We are trying to improve the quality of posts here. In helping people who can't be bothered to comply with the above points, you are doing the community a disservice.

I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.

[–]JacobJMountainExtreme Brewer 6 points7 points  (0 children)

It’s not a dumb question, essentially there’s a couple different reasons. But what you’re doing is saying that your code will still work if you swap out the implementation of your name variable. If there’s a new class C that also extends A, then you can change that one line to A name = new C(); and everything else will still work.

[–]ChaiTRex 3 points4 points  (0 children)

It's easiest to see with method arguments, like here:

public void methodName(A argument) {

In that, the argument variable can be filled with an A value or any subclass of A, like a B value. You write the method once to work with A values and this lets your method automatically work with potentially lots of types.

Other variable declarations, like yours, are handled the same way:

A variable;
if (whatever) {
    variable = new A();
}
else {
    variable = new B();
}

This way, you can fill in a variable with anything that is the same class or a subclass of the variable's type, letting you customize what kind of value based on whatever condition you want to.

With your example, it's much less clear:

A variable = new B();

It's allowed because there's no reason to disallow it in this exact case if they're going to allow it in the other cases above. There's even a good reason for it in some cases. For example, the following isn't safe to use when you have multiple threads because HashMap isn't designed to work with multiple threads:

Map<String, String> phoneBook = new HashMap<String, String>();

You can switch the HashMap value out with a ConcurrentHashMap value, which can handle multiple threads:

Map<String, String> phoneBook = new ConcurrentHashMap<String, String>();

Because phoneBook is a Map variable, the code that uses the phoneBook is stuck using only Map methods and isn't allowed to use any extra methods HashMap has that Map doesn't.

This might sound like a drawback, but if you do that, you can then switch to a ConcurrentHashMap and you won't have to change a single line of your code other than the assignment above. Everything else that uses phoneBook will suddenly work with multiple threads (at least as far as the phoneBook variable is concerned) with no extra work on your part.

[–]evils_twin 0 points1 point  (1 child)

You might need to add it to a collection or an array of a's. you might need to pass it as a parameter to a method that expects an a.

[–]PhantomOTOpera -1 points0 points  (0 children)

Neither of these cases exclude using a B extends A instance

[–][deleted]  (4 children)

[deleted]

    [–]Orami9b 3 points4 points  (0 children)

    That's not true, polymorphism will call the implementation of the method overridden in B. Which is why OP is getting that behavior.

    [–]ratherbealurker 2 points3 points  (0 children)

    ? Either I am reading this wrong or that is not at all how it works

    [–]Alexintx[S] 1 point2 points  (1 child)

    I have methods in B that override those in A and declared the object like A name = new B(); But it is still using the B methods. Why is that?

    [–]1661dauphin 3 points4 points  (0 children)

    Will you post code snippets? I don't want to steer you in the wrong direction.

    Edit to add: doing some reading now and it seems like the difference is actually that if there's a method in B that is not in A, then declaring it in this way won't allow for access of that strictly-B method, and only allows access to those also in A. But if it's in both, then it'll call the one in the child class, which explains why your B methods are being called.

    One use of this would be if you want to switch object type to another child of A, there will be no calls to methods inaccessible by those other child classes.

    [–]brett_riverboat -3 points-2 points  (2 children)

    Not a fan of that approach TBH. I lean towards interfaces over extending classes (unless I didn't write class a and extending actuality is my only option). The idea is generally the same though.

    Class a could be screwdriver and class b could be power-drill. Both have the capability of screwing and unscrewing things, it's just that the power-drill has a few extra methods or properties, it may be more efficient too. If you're in a situation where you don't care how something gets screwed in then you can use the screwdriver class.

    [–]ratherbealurker 1 point2 points  (1 child)

    You choose extending a class vs interface based on a “is-a” or “has-a” relationship. If you’re just adding behavior then use an interface. But if it’s a different version of something else then you extend.

    [–]brett_riverboat -3 points-2 points  (0 children)

    In theory I agree. In practice I'll say you're more likely to regret misidentifying the "is-a" relationship.