{"id":433155,"date":"2024-02-15T09:45:38","date_gmt":"2024-02-15T08:45:38","guid":{"rendered":"https:\/\/blog.jetbrains.com\/?post_type=idea&#038;p=433155"},"modified":"2025-09-17T12:22:16","modified_gmt":"2025-09-17T11:22:16","slug":"easy-hacks-how-to-implement-polymorphism-in-java","status":"publish","type":"idea","link":"https:\/\/blog.jetbrains.com\/en\/idea\/2024\/02\/easy-hacks-how-to-implement-polymorphism-in-java","title":{"rendered":"Easy Hacks: How To Implement Polymorphism in Java"},"content":{"rendered":"\n<p>Polymorphism is the ability of an object to take on different forms. In programming, this means that a variable or a method can have different behaviors depending on the type of object it represents. While the term may sound intimidating to beginners, polymorphism is a powerful tool: it helps you reduce coupling, increases reusability, and helps to make your code easier to read.<\/p>\n\n\n\n<p>Imagine you have a class called <code>Vehicle<\/code>, and two subclasses called <code>Car<\/code> and <code>Bike<\/code>. All classes may have a common method called <code>drive()<\/code>, and perhaps a property to specify the <code>numberOfWheels<\/code>. Unless you need the specific details of <code>Car<\/code> or <code>Bike<\/code>, you can thus treat both as a <code>Vehicle<\/code> throughout your code base. With polymorphism, you can write code that can handle objects of different classes in a generic way without having to know the specificities of each.<\/p>\n\n\n\n<p>In this blog post, we\u2019ll be looking at a practical example of polymorphism in action!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Polymorphism through inheritance<\/h2>\n\n\n\n<p>For the purposes of this post, we\u2019re assuming you\u2019ve already learned what inheritance is and are familiar with Java keywords such as <code>abstract<\/code>, <code>implements<\/code>, and <code>extends<\/code>.<\/p>\n\n\n\n<p>Polymorphism works in Java and other programming languages through inheritance \u2013 either by building a hierarchy of classes with one common superclass or by implementing a common interface for several classes.<\/p>\n\n\n\n<p>To illustrate polymorphism, let&#8217;s consider the example we used in the introduction to this blog post and take a closer look at how we can use polymorphism to write code that can work with cars, bikes, and other types of vehicles.<\/p>\n\n\n\n<p>Let\u2019s start off with an <code>abstract<\/code> class called <code>Vehicle<\/code> that contains common methods and properties that all vehicles share:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"wpcustom\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">public abstract class Vehicle {\n    private final int numberOfWheels;\n\n    public Vehicle(int numberOfWheels) {\n        this.numberOfWheels = numberOfWheels;\n    }\n\n    public int getNumberOfWheels() {\n        return numberOfWheels;\n    }\n\n    public abstract void drive();\n}<\/pre>\n\n\n\n<p>While the <code>Vehicle<\/code> class is <code>abstract<\/code> and can\u2019t be instantiated directly, it does specify that every subclass has to expose their <code>numberOfWheels<\/code>, and implement a method \u2013 <code>drive()<\/code>.<\/p>\n\n\n\n<p>Now, let\u2019s add two subclasses, <code>Car<\/code> and <code>Bike<\/code>, that extend the <code>Vehicle<\/code> class as follows:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"wpcustom\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">public class Car extends Vehicle {\n    private final String brand;\n    private final String model;\n\n    public Car(String brand, String model) {\n        super(4);\n        this.brand = brand;\n        this.model = model;\n    }\n\n    public String getBrand() {\n        return brand;\n    }\n\n    public String getModel() {\n        return model;\n    }\n\n    @Override\n    public void drive() {\n        System.out.println(\"Driving a car!\");\n    }\n}\n\npublic class Bike extends Vehicle {\n    private final int numberOfGears;\n\n    public Bike(int numberOfGears) {\n        super(2);\n        this.numberOfGears = numberOfGears;\n    }\n\n    public int getNumberOfGears() {\n        return numberOfGears;\n    }\n    @Override\n    public void drive() {\n        System.out.println(\"Cycling along\");\n    }\n}<\/pre>\n\n\n\n<p>If you look closely at the code, you\u2019ll see <code>Car<\/code> extends <code>Vehicle<\/code> and also has a <code>brand<\/code> and <code>model<\/code> property. The constructor sets the <code>numberOfWheels<\/code> to <code>4<\/code>. For <code>Bike<\/code>, you\u2019ll see it also extends <code>Vehicle<\/code> and exposes its own <code>numberOfGears<\/code> in addition to the number of gears inherited from <code>Vehicle<\/code>. In the constructor, it sets the <code>numberOfWheels<\/code> to <code>2<\/code>. Both classes also override the <code>drive()<\/code> method, each with its own implementation.<\/p>\n\n\n\n<p>You can use the <a href=\"https:\/\/www.jetbrains.com\/help\/idea\/viewing-structure-and-hierarchy-of-the-source-code.html#ws_type\" target=\"_blank\" rel=\"noopener\"><em>Type Hierarchy<\/em> action in IntelliJ IDEA<\/a> (use <em>\u2303H<\/em> on macOS or <em>Ctrl+H<\/em> on Windows\/Linux) to view the hierarchy of classes, methods, and calls and to explore the structure of source files. For the <code>Vehicle<\/code> hierarchy and all subclasses, this is how it looks:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1030\" height=\"370\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/01\/image-21.png\" alt=\"Class hierarchy in IntelliJ IDEA\" class=\"wp-image-433189\"\/><\/figure>\n\n\n\n<p>Now, let\u2019s see what we can do with the resultant class hierarchy!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Polymorphism in action<\/h2>\n\n\n\n<p>You can use polymorphism to work with any <code>Vehicle<\/code> type when no specialized properties or methods are needed. For example, you can create a <code>Driver<\/code> class that is able to drive any <code>Vehicle<\/code>:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"wpcustom\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">public class Driver {\n    private final String name;\n    private final Vehicle vehicle;\n\n    public Driver(String name, Vehicle vehicle) {\n        this.name = name;\n        this.vehicle = vehicle;\n    }\n\n    public void drive() {\n        System.out.println(name + \" is starting to drive...\");\n        vehicle.drive();\n    }\n}<\/pre>\n\n\n\n<p>When you call the <code>drive()<\/code> method on <code>Driver<\/code>, it prints out the name of the driver and then invokes the <code>drive()<\/code> method of the <code>Vehicle<\/code>. Here\u2019s an example program where two drivers each operate a different type of <code>Vehicle<\/code> (a <code>Car<\/code> and a <code>Bike<\/code>):<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"1074\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/01\/image-22.png\" alt=\"Run Java in IntelliJ IDEA\" class=\"wp-image-433200\"\/><\/figure>\n\n\n\n<p>Thanks to polymorphism, the drivers can simply work with the generic <code>Vehicle<\/code>. Unless they need data or behavior that is specific to <code>Car<\/code> or <code>Bike<\/code>, they don\u2019t have to do type casting or create <code>if<\/code>\/<code>else<\/code> branches to work with different vehicle types. This definitely improves code readability!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Flexibility of polymorphism<\/h2>\n\n\n\n<p>There\u2019s another benefit to polymorphism \u2013 flexibility! Imagine you have to introduce a new <code>Vehicle<\/code> type into your project \u2013 <code>Train<\/code>.<\/p>\n\n\n\n<p>If you\u2019re using IntelliJ IDEA, place the text caret on the <code>Vehicle<\/code> class name, press <em>\u2325+Enter<\/em> on macOS or <em>Alt+Enter<\/em> on Windows\/Linux, and select the <em>Implement abstract class<\/em> action. Give the new class a name, and then press <em>Enter<\/em> again. The IDE will then prompt which methods to implement.<\/p>\n\n\n\n<img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/01\/implement-abstract-class.png\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/01\/implement-abstract-class.gif\" alt=\"Implement abstract class in IntelliJ IDEA\" \/>\n\n\n\n<p>If you just want to see or copy the code, here\u2019s the newly created <code>Train<\/code> class:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"wpcustom\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">public class Train extends Vehicle {\n    public Train(int numberOfWheels) {\n        super(numberOfWheels);\n    }\n\n    @Override\n    public void drive() {\n        System.out.println(\"Choo choo!\");\n    }\n}<\/pre>\n\n\n\n<p>Like any other <code>Vehicle<\/code>, any <code>Train<\/code> has the <code>numberOfWheels<\/code> property and the <code>drive()<\/code> method.<\/p>\n\n\n\n<p>Now, consider the <code>Driver<\/code> class we introduced in the previous section. As you can see from the output below, it does not need any changes in order to be able to work with <code>Train<\/code>! You can simply create a new <code>Driver<\/code> and ask it to drive the newly introduced vehicle.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"1280\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2024\/01\/image-23.png\" alt=\"\" class=\"wp-image-433247\"\/><\/figure>\n\n\n\n<p>Polymorphism helps to make your code more flexible and simplifies the process of introducing changes.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Specialized vs. generic classes<\/h2>\n\n\n\n<p>When working with polymorphism in your code base, you can avoid using specialized subclasses when all you need is the properties and methods exposed by the superclass. However, you may still want to use the more specialized classes in some cases.<\/p>\n\n\n\n<p>An easy way to create classes and methods that require a specialized type of <code>Vehicle<\/code>, is to use the subclass type directly. For example, a <code>driveTrain(Train train)<\/code> method will only accept <code>Train<\/code> and never <code>Car<\/code>, <code>Bike<\/code>, or any other <code>Vehicle<\/code> type (unless you introduce a subclass of <code>Train<\/code>):<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"814\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/pasted-image-0-1.png\" alt=\"\" class=\"wp-image-621354\"\/><\/figure>\n\n\n\n<p>You may also encounter cases where you do want to work with the generic <code>Vehicle<\/code>, while still being able to look at specific properties as needed. Let\u2019s say you have a collection of <code>Vehicle<\/code> classes, and want to write their details to the output. Here\u2019s how the collection would look as an <code>ArrayList&lt;Vehicle&gt;<\/code>:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"wpcustom\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">var vehicles = new ArrayList&lt;Vehicle>();\nvehicles.add(new Car(\"BMW\", \"1\"));\nvehicles.add(new Bike(16));\nvehicles.add(new Train(80));<\/pre>\n\n\n\n<p>If you just want to write the number of wheels for each vehicle, all you have to do is iterate over this collection, and through polymorphism, then get the value of the <code>numberOfWheels<\/code> property:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"wpcustom\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">for (var vehicle : vehicles) {\n    System.out.printf(\"Number of wheels: %d%n\", vehicle.getNumberOfWheels());\n}<\/pre>\n\n\n\n<p>When you need the details of a specific <code>Vehicle<\/code> type, you can check the type and use a type cast to work with a subclass such as <code>Bike<\/code>:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"wpcustom\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">for (var vehicle : vehicles) {\n    System.out.printf(\"Number of wheels: %d%n\", vehicle.getNumberOfWheels());\n        \n    if (vehicle instanceof Bike) {\n        var bike = (Bike) vehicle;\n\n        System.out.printf(\"Number of gears: %d%n\", bike.getNumberOfGears());\n    }\n}<\/pre>\n\n\n\n<p>Doing the type conversions for every <code>Vehicle<\/code> type can be quite verbose, so you could also use pattern matching with a <code>switch<\/code> expression or statement:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"wpcustom\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">for (var vehicle : vehicles) {\n    System.out.printf(\"Number of wheels: %d%n\", vehicle.getNumberOfWheels());\n\n    switch (vehicle) {\n        case Bike bike -> System.out.printf(\"Number of gears: %d%n\", bike.getNumberOfGears());\n        case Car car -> System.out.printf(\"Brand and model: %s %s%n\", car.getBrand(), car.getModel());\n        default -> System.out.println(\"This is just a generic Vehicle\");\n    }\n}<\/pre>\n\n\n\n<p><em>Tip: Check out Mala Gupta\u2019s <\/em><a href=\"https:\/\/blog.jetbrains.com\/en\/idea\/2023\/02\/pattern-matching-in-java-5-examples-for-busy-developers\"><em>Pattern Matching in Java blog post<\/em><\/a><em> for more insights on pattern matching!<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Summary<\/h2>\n\n\n\n<p>In this post, we\u2019ve looked at an example of using polymorphism in Java code.<\/p>\n\n\n\n<p>Polymorphism allows objects of different classes to be treated as the same type. By creating a hierarchy of classes, implementing a common interface, or extending a common superclass, you can write code that works with common properties and methods while still retaining the ability to work with the specialized classes when needed.<\/p>\n\n\n\n<p><strong>Go and give it a <\/strong><a href=\"https:\/\/www.jetbrains.com\/idea\/\" target=\"_blank\" rel=\"noopener\"><strong>try in IntelliJ IDEA<\/strong><\/a><strong>!<\/strong><\/p>\n","protected":false},"author":118,"featured_media":444763,"comment_status":"closed","ping_status":"closed","template":"","categories":[4759,5088],"tags":[40,155,743],"cross-post-tag":[],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/idea\/433155"}],"collection":[{"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/idea"}],"about":[{"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/types\/idea"}],"author":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/users\/118"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/comments?post=433155"}],"version-history":[{"count":10,"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/idea\/433155\/revisions"}],"predecessor-version":[{"id":621366,"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/idea\/433155\/revisions\/621366"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/media\/444763"}],"wp:attachment":[{"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/media?parent=433155"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/categories?post=433155"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/tags?post=433155"},{"taxonomy":"cross-post-tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/en\/wp-json\/wp\/v2\/cross-post-tag?post=433155"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}