1. Pegasus

Let's take a deeper look at the third principle of OOP: inheritance. This is a very interesting topic that you will use often. To the uninitiated, programming is indistinguishable from magic. So let's start with an interesting analogy...;

Let's say you are a wizard who wants to create a flying horse. On the one hand, you could try conjuring a pegasus. But because pegasi do not exist in nature, this will be very difficult. You will have to do a lot yourself. It's much easier to take a horse and conjure its wings.

In programming, this process is called "inheritance". Suppose you need to write a very complex class. It takes a long time to write code from scratch and then test everything for a long time to look for errors. Why go the hard way? It's better to look to see whether such a class already exists.

Suppose you find a class whose methods implement 80% of the functionality you need. What do you do with it next? You could just copy its code into your class. But this solution has several drawbacks:

  1. The class you find may already be compiled into bytecode, and you may not have access to its source code.
  2. The source code of the class is available, but you work for a company that could be sued for a couple of billion for using even 6 lines of someone else's code. And then your employer will sue you.
  3. Unnecessary duplication of a large amount of code. Additionally, if the author of an external class finds a bug in it and fixes it, you will still have the bug.

There is a more elegant solution, and it doesn't require getting legal access to the original class's code. In Java, you can simply declare that class as the parent of your class. That will be equivalent to adding the code for that class to your own code. Your class will see all the data and all the methods of the parent class. For example, you can do this: we inherit "horse" and then add "wings" to get a "pegasus"


2. Common base class

Inheritance can be used for other purposes as well. Let's say you have ten classes that are very similar. They have the same data and methods. You can create a special base class, move the data (and associated methods) into this base class, and declare those ten classes to be descendants. In other words, in each class indicate that its parent class is this base class.

Just as the advantages of abstraction are revealed only along side encapsulation, so too are the advantages of inheritance much enhanced when using polymorphism. But you will learn about that a little later. Today we will look at several examples of using inheritance.

Chess pieces

Suppose we are writing a program that plays chess with a human user. Accordingly, we need classes to represent the pieces. What classes would they be?

If you've ever played chess, the obvious answer is King, Queen, Bishop, Knight, Rook and Pawn.

But the classes themselves would still need to store information about each piece. For example, the x and y coordinates, and the value of the piece. After all, some pieces are more valuable than others.

In addition, the pieces move differently, which means that the classes will implement different behavior. Here's how you could define them as classes:

class King
{
   int x;
   int y;
   int worth;

   void kingMove()
   {
     // Code that decides
     // how to move
     // the king
   }
}
class Queen
{
   int x;
   int y;
   int worth;

   void queenMove()
   {
     // Code that decides
     // how to move
     // the queen
   }
}
class Rook
{
   int x;
   int y;
   int worth;

   void rookMove()
   {
     // Code that decides
     // how to move
     // the rook
   }
}
class Knight
{
   int x;
   int y;
   int worth;

   void knightMove()
   {
     // Code that decides
     // how to move
     // the knight
   }
}
class Bishop
{
   int x;
   int y;
   int worth;

   void bishopMove()
   {
     // Code that decides
     // how to move
     // the bishop
   }
}
class Pawn
{
   int x;
   int y;
   int worth;

   void pawnMove()
   {
     // Code that decides
     // how to move
     // the pawn
   }
}

This is a very primitive description of chess pieces.

Common base class

And here's how you could use inheritance to reduce the amount of code. We can bring the common methods and data into a common class. We'll call it ChessItem. There's no point in creating objects of the ChessItem class, since the class doesn't correspond to any chess piece. That said, the class will prove very useful:

class King extends ChessItem
{
   void kingMove()
   {
     // Code that decides
     // how to move the king
   }
}
class Queen extends ChessItem
{
   void queenMove()
   {
     // Code that decides
     // how to move the queen
   }
}
class Rook extends ChessItem
{
   void rookMove()
   {
     // Code that decides
     // how to move the rook
   }
}
class ChessItem
{
   int x;
   int y;
   int worth;
}
class Knight extends ChessItem
{
   void knightMove()
   {
     // Code that decides
     // how to move the knight
   }
}
class Bishop extends ChessItem
{
   void bishopMove()
   {
     // Code that decides
     // how to move the bishop
   }
}
class Pawn extends ChessItem
{
   void pawnMove()
   {
     // Code that decides
     // how to move the pawn
   }
}

This is a great way to simplify the code for similar objects. The benefits are particularly noticeable when there are thousands of different objects and hundreds of classes in the project. So properly selected parent (base) classes let you not only greatly simplify the logic, but also reduce the code tenfold.


3. Class inheritance — extends

So what does it take to inherit a class? For one class to inherit another, you need to write the extends keyword after the child class declaration and then write the name of the parent class. It usually looks something like this:

class Descendant extends Parent

This is what you need to write when declaring the Descendant class. By the way, a class can inherit only one class.

In the picture, we see that a cow inherited a pig, which inherited a chicken, which inherited an egg. Only one parent! Such inheritance is not always logical. But when all you have is a pig and you really need a cow, programmers often cannot resist the urge to make a cow out of a pig.

Java does not have multiple inheritance: a class cannot inherit two classes. Each class can have only one parent class. If no parent class is specified, the parent class is Object.

That said, Java does have multiple inheritance of interfaces. This mitigates the problem slightly. We'll talk about interfaces a little later, but for now let's continue to explore inheritance.


3
Task
Java Syntax,  level 10lesson 11
Locked
Correct answer: d = 2.941
A spaceship flew to planet of Paleo-Know, and met there creatures that didn't even know integer arithmetic. But this whole story has nothing to do with our task. It's only here as an amazing fact to get your attention. Meanwhile, you need to add one cast operation to the code and get the correct answer.
12
Task
New Java Syntax,  level 12lesson 7
Locked
Numbers and strings
The add method should add up the input arguments and return a string like this: a+b=sum For example, if you pass (7, 8) to the method, then it should return the string "7+8=15". But the method is not working properly at present. Your task is to fix it.
12
Task
New Java Syntax,  level 12lesson 7
Locked
But that's how I want it
Implement the toCustomString method so that it converts a Number to a String according to a specific type-dependent rule: - if the argument is a Byte object, then divide it by 2 and convert it to a string, adding the letter "b" at the end; - if the argument is an Integer object, then divide it by 3