0
interface Readable {
    public void printTitle();
}

class WebText implements Readable {
    public String title;

    public void printTitle(){
        System.out.println("This Webpage title is "+ title);
    }

    public void setTitle(String title){
        this.title = title;
    }
}

class Blog extends WebText {

    public void printTitle(){
        System.out.println("The Blog title is " + title);
    }
}

class ReadingTester{
    public static void main(String [] arg) {
        Blog b1 = new Blog();
        WebText b2 = new Blog();

        b1.setTitle("How to upcast");
        b2.setTitle("Dangers of upcasting");

        b1.printTitle();
        b2.printTitle();

    }
}

The above code is on a homework assignment that I am working on but I am really unsure about what is going on. When I run the code, it outputs:

The Blog title is: How to upcast

The Blog title is: Dangers of upcasting

What I am confused on is why the second one prints out "The Blog title is" instead of "This Webpage title is:". Since b2 is upcasted to a WebText shouldn't that class be the one that responds? Everything that I find online says that upcasting is safe but is this an example of when it isn't? I'm really confused and would really appreciate some help thank you so much!

Ben Naylor
  • 29
  • 6
  • Why do you think this is not safe? – Andy Turner Oct 01 '19 at 07:12
  • When you create a Blog object you get a Blog object, when you define it as a WebText object it means you can only access it using the public methods in WebText but it is still a Blog object. – Joakim Danielson Oct 01 '19 at 07:13
  • If i can access it using the public methods in webtext shouldn't that mean that the printTitle in WebText would have printed instead of the printTitle in Blog? – Ben Naylor Oct 01 '19 at 07:15
  • b2 is referencing a Blog object in memory. it is natural to print "The Blog title is: Dangers of upcasting" – Oğuzhan Aygün Oct 01 '19 at 07:17
  • What I don't get is that we always were taught that when you upcast, the higher class is the one that responds. This would mean that b2 would respond based off of the WebText class's method which should print "This webpage.." which it isn't. What I want to know is why does the name of the method being the same cause this to not happen? – Ben Naylor Oct 01 '19 at 07:21
  • @BenNaylor Either what you were taught was wrong, or you misunderstood it. – Sweeper Oct 01 '19 at 07:22

2 Answers2

1

The printTitle in Blog overrides the printTitle in WebText. Since b2 is actually an instance of Blog at runtime, calling printTitle will call the one in Blog, even though at compile time, b2 is of type WebText. This is a kind of polymorphism.

This behaviour is actually desirable, because it allows you to have a variable, of type WebText, that is able to store many different types of web texts, including blogs, news articles, and stack overflow answers. Each of those types may choose to print their titles differently. This post might help you understand why we do this better.

Why is this said to be safe then?

This is safe, as in that it doesn't throw an exception. It is unsafe, s as in b2.printTitle might not call the method in WebText, but you shouldn't assume that in the first place anyway, unless the method is final.

Sweeper
  • 213,210
  • 22
  • 193
  • 313
1

At compile time, WebText b2 = new Blog(); checks whether the method calls to b2 can be fulfilled. It sees that Blog has both setTitle and printTitle. So it treats b2 like a Blog.

If you had a different method in Blog, let's say, printTwice(), and you tried calling b2.printTwice() the compiler would throw a compile time error as it can't treat WebText object as a Blog object (as b2 can't reference a Blog object)

Abishek Aditya
  • 802
  • 4
  • 11