I refer to the second edition of Java, which is easy to understand.
When developing a program, it is often the case that a class similar to the previously created class is created. At this time, it is inefficient to copy and paste the previously created class, so you can write efficient code by inheriting the previously created class.
Hero.java
public class Hero{
private String name = "hoge";
private int Hp = 100;
public void attack(Monster m){
m.hp -= 5;
}
public void recover(){
this.Hp += 5;
}
}
SuperHero.java
public class SuperHero{
private String name = "hoge";
private int Hp = 100;
private boolean flying;
public void attack(Monster m){
m.hp -= 5;
}
public void recover(){
this.Hp += 20;
}
public void fly(){
this.flying = true;
System.out.println("Flight status");
}
public void land(){
this.flying = false;
System.out.println("Landing condition");
}
}
In this code, when I add a new method to the Hero class, I need to change that change to the SuperHero class as well. Most of the code in the SuperHero and Hero classes is similar, which makes the overall outlook difficult and maintenance cumbersome. So, use ** inheritance ** to eliminate code duplication.
SuperHero.java
public class SuperHero extends Hero{
private boolean flying;
public void attack(Monster m){
m.hp -= 10;
}
public void recover(){
this.Hp += 20;
}
public void fly(){
this.flying = true;
System.out.println("Flight status");
}
public void land(){
this.flying = false;
System.out.println("Landing condition");
}
}
By rewriting as described above, it is possible to define a SuperHero class that inherits the field methods of the Hero class. In this case, the Hero class is called the parent class (super class), and the SuperHero class is called the child class (subclass).
Java does not allow multiple inheritance. Specifically, if there is a Hero class and a Moster class, it is not possible to define a HeroMonster class by inheriting those two classes. That is, one child class cannot be defined with a plurality of parent classes as parents. It is possible to override the method defined in the parent class with the child class (called method override). Some Java classes are not allowed to inherit. An example is the String class. It is also possible to declare a class that does not allow it to be inherited by itself. Add the final operator when declaring a class.
Main.java
public final class Main{
public static void main(Strign args[]){
//Contents of the main function
}
}
Similarly, to prevent method overriding, add the final operator when declaring the method.
Consider what happens to the behavior of the created instance due to inheritance. This will be described using the Hero class shown above and the SuperHero class. The SuperHero instance contains a Hero instance inside and has a dual structure. When a method execution command is called from outside the instance, the multi-structured instance calls * as much as possible the method * of the child instance on the outside. Specifically, when the recover method is called from the SuperHero instance, the overridden method is called, and the recover method of the Hero instance is not called. Describes access to the parent instance. As an additional specification, if you recover in flight, you will recover Hp by 25 points. When calling the method field of the parent instance
super. method name (argument) super. field name
And.
SuperHero.java
public class SuperHero extends Hero{
private boolean flying;
public void attack(Monster m){
m.hp -= 10;
}
public void recover(){
this.Hp += 20;
if(this.flying){
super.recover();
}
}
public void fly(){
this.flying = true;
System.out.println("Flight status");
}
public void land(){
this.flying = false;
System.out.println("Landing condition");
}
}
At this time, if you call super.recover () with recover (), it will be called as this.recover () and you will get into an infinite loop, so be careful.
We have already explained that inherited instances have a multi-layered structure. Next, consider how the instance is built. Execute the following program with reference to the above program.
Hero.java
public class Hero{
private String name = "hoge";
private int Hp = 100;
public void attack(Monster m){
m.hp -= 5;
}
public void recover(){
this.Hp += 5;
}
Hero(){
System.out.println("Hero constructor");
}
}
SuperHero.java
public class SuperHero extends Hero{
private boolean flying;
public void attack(Monster m){
m.hp -= 10;
}
public void recover(){
this.Hp += 20;
}
public void fly(){
this.flying = true;
System.out.println("Flight status");
}
public void land(){
this.flying = false;
System.out.println("Landing condition");
}
SuperHero(){
System.out.println("SuperHero constructor");
}
}
Main.java
public class Main{
public static void main(Strign args[]){
SuperHero sh = new SuperHero();
}
}
First, the parent instance part is created, and then the child instance part is created on the outside. Finally, the JVM automatically calls the constructor of the SuperHero class. The execution result is as follows.
Execution result
Hero constructor
SuperHero constructor
Notice that the constructor of the Hero instance, which is the inner instance, is also called. This is because the Java rule is "All constructors must call the constructor of the internal instance at the beginning."
SuperHero.java
public class SuperHero extends Hero{
.
.
.
SuperHero(){
super();
System.out.println("SuperHero constructor");
}
}
The compiler automatically inserts super ().
A constructor that is not defined in the parent instance part may be called by the constructor in the child instance part, resulting in an error. Specifically, it will be described using the Human class and the Soldier class.
Human.java
public class Human{
private String name;
private int Hp;
private int Mp;
Human(String name){
this.name = name;
this.Hp = 100;
this.Mp = 100;
}
Human(String name, int hp, int mp){
this.name = name;
this.Hp = hp;
this.Mp = mp;
}
}
Human.java
public class Soldier{
.
.
.
}
Main.java
public class Main{
public static void main(Strign args[]){
Soldier soldier = new Soldier();
}
}
In this code, the Soldier class does not have a constructor, so the constructor of the parent class Human class is called. However, since the Human class does not have a no-argument constructor, this code will result in an error. To prevent this, forcibly call the constructor with arguments in the constructor of the Soldier class to solve it.
Human.java
public class Soldier{
.
.
.
Soldier(){
super("hoge");
}
}
Correct inheritance is inheritance according to the "is-a principle".
Child class is-a Parent class (child class is part of parent class)
Explained in the code shown above, the SuperHero class is part of the Hero class. It is a mistake that the Hero class is part of the SuperHero class. Inheritance is a useful feature, but incorrect inheritance can lead to programmatic inconsistencies and the inability to take advantage of diversity.
An abstract class is a class that has an abstract method field. A concrete class that inherits from an abstract class must override the methods defined in the abstract class. In addition, when inheriting multiple abstract classes, it can be realized by defining the abstract class as an interface (details are 2.3). The significance of the existence of abstract classes and methods is a material for efficiently creating safe programs when the number of developers increases in the future. To give a concrete example, if you proceed with development without an abstract class, the content of a method is not decided at this stage, and the content of the method may be left empty. When another developer sees this method, I don't know if the content needs to be rewritten. However, if it is defined as an abstract method, it needs to be overwritten, so it can be seen that the content needs to be rewritten. From this, you can develop with confidence by using abstract methods.
Character.java
public class Character{
.
.
public abstract void atttack(Monster m);
}
The attack method is embodied in a class that inherits the Character class.
Character.java
public abstract class Character{
.
.
public abstract void atttack(Monster m);
}
Define a class as an abstract class to prevent the creation of incomplete class instances.
In Java, abstract classes with a particularly high degree of abstraction can be treated specially as interfaces. As a condition to treat as an interface
--All methods are abstract methods --Basically, it doesn't have any fields (if you define a field, it will be treated as a constant).
There is.
Creature.java
public interface Creature{
public abstract void run(); //public abstract can be omitted
}
When a variable is defined in the interface, public static final is supplemented and treated as a constant. When implementing the Creature class, do as follows.
Pig.java
public class Pig implements Creature{
public void run(){
System.out.println("Pig escaped");
}
}
By defining the interface
--You can force multiple child classes that implement an interface to implement a common set of methods. --If a class implements an interface, it is guaranteed to have at least the methods defined by that interface.
There is a merit.
Recommended Posts