[JAVA] Let's be lazy with inheritance and override

Inheritance is not good ~ ...

At school, I came up with a great succession, so I talked about succession with momentum. Since it is almost ad lib, abstract is also available.

So what is inheritance?

Inheritance is to take in another class and create an instance of a method or variable written in another class. You can treat it as if it were a method written in your own class or a variable. ..

Use the ʻextends` keyword for inheritance. The inherited class is called the parent class (super class), and the inherited and extended class is called the child class (Sub Class).

Parent class


class SuperClass{
  public int num = 10;

  public void superClassMethod(){
    System.out.println("It's a parent class ~");
  }
}

Child class


class SubClass extends SuperClass{
  //I don't write anything for the time being
}

Class with main method


class Test{
  public static void main(String[] args){
    SubClass instance = new SubClass();
    instance.superClassMethod();
  }
}

// >>>"It's a parent class" is displayed.

Looking at the relationship in the figure, it looks like this. 名称未設定1.png It feels like the child class includes the parent class. If you think in Japanese, are you a parent among your children? You might think, but do your best and get used to it ...

The child class can use variables and methods that are not private to the parent class. If you want to use private variables of the parent class, you can prepare Getter / Setter methods.

Child class


class SubClass extends SuperClass{
  void test(){
    //Refer to the variable of the parent class
    System.out.println(num);  //10

    //Try to call the method of the parent class
    superClassMethod();
  }
}

By inheriting like this, I was able to make it feel like I had incorporated another class into my class. However, if you can use the same method in various places, you can use a class method.

That's not true. </ b>

Inheriting allows override </ b>. let's try it.

Let's override

Override allows you to add and define superclass methods. Why do you need that? I'll talk about that later, so wait a minute.

Parent class


class SuperClass{
  public void printMethod(){
    System.out.println("It's a parent class ~");
  }
}

Child class


class SubClass extends SuperClass{
  @Override
  public void printMethod(){
    System.out.println("I overridden it!");
  }
}

In this way, the method can be overridden by defining the method with the same name and the same argument as the method of the parent class in the child class.

The @Override annotation is written before the method. This is to indicate to the Java compiler that "this method is overriding" and has nothing to do with the behavior of the program. I don't know if it will be overridden without this, and if the name does not match the method of the parent class, an error will be issued, so it is a standard to add it.

If you want to know more details, read the following. People don't have to read it separately.

What if I don't have @Override?

Why do you need something that has nothing to do with operation? For example, in the example, a method called printMethod () is added and defined, but a slight typographical error results in the method name being priiiiiiiiiintMethod ().

Child class


class SubClass extends SuperClass{
  public void priiiiiiiiiintMethod(){
    System.out.println("I overridden it!");
  }
}

If it doesn't have @Override, it can compile normally as a method that you aren't trying to override. If the caller of this method makes a typo again (?), It can be used normally, so it takes time to notice that it is not doing what you want.

It is better to write the @Override annotation to prevent such human error. When working in the IDE, the input completion function works well.

Why do you do such a troublesome thing?

I thought, "If you want to inherit it separately, you should just make another class by copying it," but inheritance is much more intelligent than we think.

Because you can reduce the copy code

First, you don't have to copy and paste when preparing similar classes, which leads to a reduction in the amount of code. "It doesn't matter if it's long"? Let's be lazy because it's annoying to hit one letter more! !! </ b>

Let's proceed with an example of programmatically creating creatures.

Try to write without inheriting

Dog


class Wanko{
  public void eat(String foodName){
    //I thought it was written about how to eat a dog

    //On the food plate...
    //Direct...
    //Attack!!(Dog eating)

    System.out.println(foodName+"ate");

    //Digest
    syouka(foodName);
  }

  public void syouka(String foodName){
    System.out.println(foodName+"Digested");
  }
}

Monkey


class Monkey{
  public void eat(String foodName){
    //I think it describes how to eat monkeys

    //Pick up by hand...
    //To your mouth...
    //I want you to carry it and eat it.

    System.out.println(foodName+"ate");

    //Digest
    syouka(foodName);
  }

  public void syouka(String foodName){
    System.out.println(foodName+"Digested");
  }
}

Now, there are some similarities to these two methods. Let's reduce the amount of code by inheriting this.

Inherit and write

First, create a base creature class </ b>. I'm not a biologist, so I don't know, but the procedure for digesting monkeys and dogs is the same.

Creatures


class Animal{
  public void eat(String foodName){
    System.out.println(foodName+"ate");

    //Digestion
    syouka(foodName);
  }
  public void syouka(String foodName){
    System.out.println(foodName+"Digested");
  }
}

Let's inherit this and write a dog class and a monkey class.

Dog


class Wanko extends Animal{
  @Override
  public void eat(String foodName){
    //I thought it was written about how to eat a dog
    //On the food plate...
    //Direct...
    //Attack!!(Dog eating)

    //super()Can be used to call the eat method of the parent class.
    super(foodName);
  }
}

Monkey


class Monkey extends Animal{
  @Override
  public void eat(String foodName){
    //I think it describes how to eat monkeys

    //Pick up by hand...
    //To your mouth...
    //I want you to carry it and eat it.

    //super()Can be used to call the eat method of the parent class.
    super(foodName);
  }
}

Suddenly I wrote super ();, but it never happened. It's just calling the method of the parent class. The parent class ʻeat () `method </ b> is used to display what was eaten and digested, which is a common process for dogs and monkeys.

By the way ... (About super ())

super () is a keyword that can be used in the constructor of the child class among the overridden methods, and the method and constructor of the parent class can be called. super () can also pass arguments and overload like normal methods.

abstract keyword

The aforementioned ʻAnimal class was a <b> class that assumed inheritance </ b>. If this is the case, the ʻAnimal class can be used by creating an instance without inheritance, but it is not a class created for that purpose.

In such a case, use the ʻabstract keyword. ʻAbstract is also attached to classes and methods.

ʻAbstract` means abstract </ b>, intangible </ b>. As the name implies, it is a abstract class, method </ b>, so please use it after making it concrete.

If you add ʻabstract to the class, instantiation by the new keyword is prohibited, and you cannot use it unless you inherit <b>. </ b> Classes with ʻabstract are called abstract classes </ b>.

If ʻabstractis added to the method, the process cannot be described and the <b> child class is forced to override. </ b> If you do not override it from the child class, it will not compile. Also, as a matter of course,super ()` cannot be used.

Creatures


class abstract Animal{
  public void eat(String foodName){
    System.out.println(foodName+"ate");

    //Digestion
    syouka(foodName);
  }
  public void syouka(String foodName){
    System.out.println(foodName+"Digested");
  }

  public abstract void printName();
}

Monkey


class Monkey extends Animal{
  @Override
  public void eat(String foodName){
    //I think it describes how to eat monkeys

    //Pick up by hand...
    //To your mouth...
    //I want you to carry it and eat it.

    //super()Can be used to call the eat method of the parent class.
    super(foodName);
  }

  //printName()You must always override the method.
  @Override
  public void printName(){
    System.out.println("Wai is a monkey");
  }
}

final keyword

You can add final to prohibit further changes. ..

When attached to a class, inheritance is prohibited. When attached to a method, overriding is prohibited. When attached to a variable, reassignment of a value other than when the variable is declared is prohibited.

Because it can be treated as a parent class type

It's really convenient to be able to upcast to the parent class type </ b>.

Bring back the animals mentioned above.

Creatures


class Animal{
  public void eat(String foodName){
    System.out.println(foodName+"ate");

    //Digestion
    syouka(foodName);
  }
  public void syouka(String foodName){
    System.out.println(foodName+"Digested");
  }
}

Dog


class Wanko extends Animal{
  @Override
  public void eat(String foodName){
    //I thought it was written about how to eat a dog
    //On the food plate...
    //Direct...
    //Attack!!(Dog eating)

    //super()Can be used to call the eat method of the parent class.
    super(foodName);
  }
}

Monkey


class Monkey extends Animal{
  @Override
  public void eat(String foodName){
    //I think it describes how to eat monkeys

    //Pick up by hand...
    //To your mouth...
    //I want you to carry it and eat it.

    //super()Can be used to call the eat method of the parent class.
    super(foodName);
  }
}

Animal, dog, and monkey have a parent-child relationship. If you have a parent-child relationship, you can do type conversion ...! </ b>

First of all, would you like to write it without type conversion?

class MeshiKue{
  public static void main(String[] args){
    Wanko dog = new Wanko();
    Monkey monkey = new Monkey();

    Gohan(dog);
    Gohan(monkey);
  }

  void Gohan(Wanko wanko){
    wanko.eat("Apple");
  }

  void Gohan(Monkey monkey){
    monkey.eat("Apple");
  }
}   

Well, it will be like this. It's okay because there are two types, but if the number of friends increases and the number of serval cats, Arai-san, and Fennec foxes increases, the Gohan () method will have to be written for each type. </ B> b> Right.

If it's all the same process, you won't be able to see it, so let's use type conversion to do just one. </ b>

class MeshiKue{
  public static void main(String[] args){
    Wanko dog = new Wanko();
    Monkey monkey = new Monkey();

    //Upcast dogs and monkeys to Animal type
    Gohan((Animal)dog);
    Gohan((Animal)monkey);
  }

  //Only one!
  void Gohan(Animal animal){
    animal.eat("Apple");
  }
}   

Casting a child class type to a parent class type is called upcast </ b>, and casting a parent class type to a child class type is called downcast </ b>. Downcasting can only be done on variables that have been upcast once.

If there is a parent-child relationship, the child class will always have the methods and variables contained in the parent class, so it can be cast to the parent class.

Even if there is a method with the same name and formal argument between two classes that do not have a parent-child relationship, it just happens to exist a method with the name and formal argument </ b>, so it is static. Type conversion cannot be performed in a typed language.

By the way

With dynamically typed languages such as Python, duck typing </ b> allows you to do this even if you happen to have a method with the same name without a parent-child relationship. Dynamically typed languages run line by line on a random basis, so it just needs to exist at that time.

at the end

Program writing Troublesome! If you think </ b>, if you look for a language function that can solve it, or if there is a shorter syntax, I believe that you will get closer to the race called a good programmer, so let's do our best to find it. !! !!