JavaRush /Java Blog /Random EN /Abstract classes in Java with concrete examples

Abstract classes in Java with concrete examples

Published in the Random EN group
Hello! In the previous lectures, we got acquainted with interfaces and figured out what they are for. Today's topic will overlap with the previous one. Let's talk about abstract classes in Java. Abstract classes in Java with specific examples - 1

Why are classes called "abstract"?

You probably remember what "abstraction" is - we already went through it :) If you suddenly forgot - it's okay, remember: this is the OOP principle , according to which, when designing classes and creating objects, it is necessary to highlight only the main properties of an entity, and discard secondary ones. For example, if we design a class SchoolTeacher- a school teacher - it is unlikely that we will need the " growth " characteristic. Indeed: for the teacher, this characteristic is not important. But if we create a class in the program BasketballPlayer- a basketball player - growth will become one of the main characteristics. So, abstract class- this is the most abstract, oh-oh-oh-so approximate "blank" for a group of future classes. This blank can not be used in finished form - too "raw". But it describes a certain general state and behavior that future classes will have - the heirs of the abstract class.

Java abstract class examples

Consider a simple car example:

public abstract class Car {

   private String model;
   private String color;
   private int maxSpeed;
  
   public abstract void gas();

   public abstract void brake();

   public String getModel() {
       return model;
   }

   public void setModel(String model) {
       this.model = model;
   }

   public String getColor() {
       return color;
   }

   public void setColor(String color) {
       this.color = color;
   }

   public int getMaxSpeed() {
       return maxSpeed;
   }

   public void setMaxSpeed(int maxSpeed) {
       this.maxSpeed = maxSpeed;
   }
}
This is what the simplest abstract class looks like. As you can see, nothing special :) Why might we need it? First of all, it describes the entity we need as abstractly as possible - the car. The word abstract is not in vain here. There are no "just cars" in the world. There are trucks, racing cars, sedans, coupes, SUVs. Our abstract class is just a "blueprint" from which we will later create car classes.

public class Sedan extends Car {
  
   @Override
   public void gas() {
       System.out.println("The sedan accelerates!");
   }

   @Override
   public void brake() {
       System.out.println("The sedan slows down!");
   }
  
}
This is in many ways similar to what we talked about in lectures about inheritance. Only there we have a class Carand its methods were not abstract. But such a solution has a number of disadvantages, which are fixed in abstract classes. First and foremost, you cannot create an instance of an abstract class:

public class Main {

   public static void main(String[] args) {

       Car car = new Car(); // Error! The Car class is abstract!
   }
}
This "chip" was implemented by the creators of Java on purpose. Once again, for the record: an abstract class is just a blueprint for future "normal" classes . You don't need blueprint copies, right? So you don’t need to create instances of an abstract class :) And if the class Carwas not abstract, we could easily create its objects:

public class Car {

   private String model;
   private String color;
   private int maxSpeed;
  
   public void gas() {
       // some logic
   }

   public  void brake() {
       // some logic
   }
}


public class Main {

   public static void main(String[] args) {

       Car car = new Car(); // Everything is OK, the machine has been created
   }
}
Now we have some kind of incomprehensible car in our program - not a truck, not a racing car, not a sedan, but in general it is not clear what. The same "just a machine" that does not exist in nature. The same example can be given with animals. Imagine if objects appeared in your program Animal- “ just an animal ”. It is not clear what kind it is, what family it belongs to, what characteristics it has. It would be strange to see him in the program. There are no "just animals" in nature. Only dogs, cats, foxes, moles and others. Abstract classes get rid of " just objects ". They give us the base state and behavior. For example, all cars must have a model , color and maximum speed., and they must also be able to accelerate and brake . That's all. This is a general abstract scheme, then you yourself design the classes you need. Note that two methods in the abstract class are also marked as abstract , and they are not implemented at all. The reason is the same: abstract classes don't create "default behaviors" for "just machines". They just say that they should be able to do all the machines. However, if you still need the default behavior, methods in the abstract class can be implemented. Java does not forbid this:

public abstract class Car {

   private String model;
   private String color;
   private int maxSpeed;

   public void gas() {
       System.out.println("Let's go!");
   }

   public abstract void brake();
  
   //getters and setters
}


public class Sedan extends Car {

   @Override
   public void brake() {
       System.out.println("The sedan slows down!");
   }

}

public class Main {

   public static void main(String[] args) {

       Sedan sedan = new Sedan();
       sedan.gas();
   }
}
Console output: "Get the gas!" As you can see, we implemented one method in the abstract class, but did not implement the second one. As a result, the behavior of our class Sedanwas divided into two parts: if you call its method gas(), it will be “pulled up” from the parent abstract class Car, and brake()we overridden the method in the class Sedan. It turned out very convenient and flexible. But now our class is not so abstract after all ? After all, he, in fact, has implemented half of the methods. In fact - and this is a very important feature - a class is abstract if at least one of its methods is abstract.. At least one of the two, at least one of the thousand methods - it doesn't matter. We can even implement all the methods and leave none of the abstract ones. There will be an abstract class without abstract methods. In principle, this is possible, and the compiler will not generate errors, but it’s better not to do this: the word abstract will lose its meaning, and your fellow programmers will be very surprised to see this :/ Moreover, if a method is marked with the word abstract, each class that inherits it must implement or be declared as abstract. Otherwise, the compiler will throw an error . Of course, each class can only inherit from one abstract class, so there is no difference between abstract and regular classes in terms of inheritance. It doesn't matter if we inherit from an abstract class or from a regular one, there can be only one parent class.

Why Java doesn't have multiple class inheritance

We have already said that there is no multiple inheritance in Java, but we didn’t really understand why. Let's try to do it now. The fact is that if Java had multiple inheritance, child classes could not decide which behavior to choose. Let's say we have two classes - Tosterand NuclearBomb:

public class Toster {
  
  
 public void on() {

       System.out.println("The toaster is on, the toast is getting ready!");
   }
  
   public void off() {

       System.out.println("The toaster is off!");
   }
}


public class NuclearBomb {

   public void on() {

       System.out.println("Взрыв!");
   }
}
As you can see, both have a on(). In the case of the toaster, it starts making toast, and in the case of the nuclear bomb, it sets off an explosion. Oh :/ And now imagine that you decided (I don't know why all of a sudden!) to create something in between. And here it is your class - MysteriousDevice! This code, of course, does not work, and we give it simply as an example of "what could it be":

public class MysteriousDevice extends Toster, NuclearBomb {

   public static void main(String[] args) {
      
       MysteriousDevice mysteriousDevice = new MysteriousDevice();
       mysteriousDevice.on(); // And what should happen here? Will we get a toast, or a nuclear apocalypse?
   }
}
Let's see what we got. The mysterious device comes from both the Toaster and the Nuclear Bomb at the same time. Both have a method on(), and as a result, it is not clear which of the methods on()should work on the object MysteriousDeviceif we call it. The object will not be able to understand this. Well, as a cherry on the cake: the Nuclear Bomb does not have a method off(), so if we didn’t guess, it will be impossible to turn off the device. Abstract classes in Java with concrete examples - 2 It is because of this "misunderstanding" when it is not clear to an object what behavior it should choose, the creators of Java abandoned multiple inheritance. However, you remember that Java classes implement many interfaces. By the way, you have already met at least one abstract class in your studies! Although, maybe I didn't notice it :)

public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar>
This is your old friend - class Calendar. It is abstract and has several successors. One of them is GregorianCalendar. You already used it in lessons about dates :) Everything seems to be clear, there is only one point left: what is the fundamental difference between abstract classes and interfaces ? Why did Java add both, and not limit itself to one thing? That might well have been enough. We'll talk about that in the next lecture! See you:)
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION