Inheritance is an important concept in object-oriented. Inheritance is another important way to improve code reusability in addition to composition. We saw in composition that composition is the functional interface of an object that is repeatedly called. As we will see, inheritance allows you to reuse existing class definitions.
Class inheritance
When we defined a class before, we started from scratch and defined each member of the class in detail. For example, the following Human class:
Copy the code code as follows:
classHuman
{
/**
*accessor
*/
public int getHeight()
{
return this.height;
}
/**
* mutator
*/
public void growHeight(int h)
{
this.height = this.height + h;
}
/**
*breath
*/
public void breath()
{
System.out.println("hu...hu...");
}
private int height;
}
From the above class definition, we can understand all the details of the class: the data members of the class, the methods of the class, and the interface of the class.
Now we need to define a new class, such as the Woman class, and assume that the Woman is quite similar to the Human class:
Human & Woman
We can start from scratch and completely define the Woman class as before:
Copy the code code as follows:
class Woman
{
/**
*accessor
*/
public int getHeight()
{
return this.height;
}
/**
* mutator
*/
public void growHeight(int h)
{
this.height = this.height + h;
}
/**
*breath
*/
public void breath()
{
System.out.println("hu...hu...");
}
/**
* new method
*/
public Human giveBirth()
{
System.out.println("Give birth");
return (new Human(20));
}
private int height;
}
A programmer will have a lot of trouble when writing the above program. Many definitions have been written in the Human class, but we have to type them again. The Woman class only adds a new giveBirth() method (this method creates and returns a new Human object).
Using inheritance, we can avoid the above duplication. Let the Woman class inherit from the Human class, and the Woman class will automatically have the functions of all public members in the Human class.
We use the extends keyword to indicate inheritance:
Copy the code code as follows:
class Woman extends Human
{
/**
* new method
*/
public Human giveBirth()
{
System.out.println("Give birth");
return (new Human(20));
}
}
In this way, we save a lot of typing. Through inheritance, we create a new class, called a derived class. The inherited class (Human) is called the base class (base class). The derived class uses the base class as the basis for its own definition, and supplements the giveBirth() method that is not defined in the base class. The inheritance relationship can be expressed as:
Inheritance: Arrow points to base class
You can use the following Test class to test:
Copy the code code as follows:
public class Test
{
public static void main(String[] args)
{
Woman aWoman = new Woman();
aWoman.growHeight(120);
System.out.println(aWoman.getHeight());
}
}
Derived layer
Through inheritance, we create the Woman class. The whole process can be divided into three levels: base class definition, derived class definition, and external use.
The level of base class definition is to define a class normally, such as the Human class definition above.
From the perspective of external users (such as a Woman class object created in the Test class), the derived class has a unified external interface:
For external users, the above interface is sufficient. From an interface perspective alone, there is nothing special about derived classes.
However, programmers must be careful when working at the level of derived class definitions:
First, the interface is mixed: the getHeight() and growHeight() methods come from the base class, while the giveBirth() method is defined inside the derived class.
There are further complications. We have previously been able to freely access the members of the class within the class (using this to refer to the object). However, when we are within the definition scope of the Woman class, we cannot access the private members of the base class Human. We remember the meaning of private: private members are only for internal use of the class. The Woman class is a new class different from the Human class, so it is located outside the Human class. In a derived class, private members of the base class cannot be accessed.
But the interesting thing is that our growHeight() and getHeight() methods still work. This shows that the private members of the base class exist, we just cannot access them directly.
In order to clarify the concept, we need to understand the generation mechanism of derived class objects. When we create an object of a derived class, Java actually creates a base class object (subobject) first, and adds The other members defined by the derived class constitute a derived class object. What external users can see are the public members of the base class and derived classes. As shown below:
Base class objects and derived class objects
The yellow color in the picture is the base class object. Members of the base layer can access each other (use this in the Human class definition to refer to the base class object).
The blue part is the new content of the derived object. I call this part the derived layer. The blue and yellow parts together form the derived object. Members of the derived layer can access each other (this in the definition of Woman). Furthermore, we can also access the public members of the base layer. For this reason, we use the super keyword to refer to the base class object, and use super.member to represent the base (public) members.
When we are in the derived layer (that is, when defining the Woman class), we cannot access the red base private members. When we are outside, we can access neither the purple derived layer private members nor the red base layer private members.
(The private members of the derived layer have access restrictions, so they are marked with a slash. The private members of the base layer have the most access restrictions, so they are marked with a cross slash)
Super is similar to this and is also an implicit parameter. When we are at different levels of class definition, this will have different meanings. Be careful with the this and super keywords.
(Java does not force the use of this and super. Java can automatically identify the ownership of members in many cases. But I think this is a good practice.)
protected
We previously introduced two access permission-related keywords, private and public, which control the external visibility of members. Now, we introduce a new access keyword: protected.
Members marked protected are visible in this class and its derived classes. This concept is easy to understand. That is to say, the protected members of the base class can be accessed by the derived layer, but cannot be accessed by the outside, as shown below:
method override
The external interface of the derived class object is ultimately composed of the public members of the base class object and the public members of the derived layer. If the public members of the base class and the public members of the derived layer have the same name, which one is displayed in the Java interface?
We have already mentioned in constructors and method overloading that Java uses both the method name and the parameter list to determine the method to be called. A method is determined by the method name and parameter list. In the above problem, if only the method names are the same but the parameter lists are different, then the two methods will be presented to the interface at the same time, which will not cause us any trouble. When making an external call, Java will decide which method to use (method overloading) based on the provided parameters.
What if the method name and parameter list are both the same? When deriving the layer, we can also use super and this to determine which method it is. When external, we only present a unified interface, so we cannot provide two methods at the same time. In this case, Java will render the derived layer methods instead of the base layer methods.
This mechanism is called method overriding. Method overrides can be put to good use to modify methods of base class members. For example, in the derived layer, that is, when defining Woman, you can modify the breath() method provided by the base class:
Copy the code code as follows:
class Woman extends Human
{/**
* new method
*/
public Human giveBirth()
{
System.out.println("Give birth");
return (new Human(20));
}
/**
* override Human.breath()
*/
public void breath()
{
super.breath();
System.out.println("su...");
}
}
Note that we are in the derived layer at this time and can still call the breath() method of the base class object through super. When we call the Woman class externally, due to method override, we can no longer call the method of the base class object.
Method overriding maintains the interface of the base class object and uses the implementation of the derived layer.
Constructor
After understanding the concepts of base class objects and derived layers, the construction methods of derived classes are easier to understand.
We need to define a constructor with the same name as the class in the definition of the derived class. In this constructor:
1. Since the base class object is created and initialized first when creating a derived object, the constructor of the base class should be called first. We can use the super(argument list) statement to call the constructor of the base class.
2. After the base class object is created, start building the derived layer (initializing the derived layer members). This is the same as the general construction method, refer to construction method and method overloading
For example, in the following program, the Human class has a constructor:
Copy the code code as follows:
classHuman
{
/**
* constructor
*/
public Human(int h)
{
this.height = h;
}
/**
*accessor
*/
public int getHeight()
{
return this.height;
}
/**
* mutator
*/
public void growHeight(int h)
{
this.height = this.height + h;
}
/**
*breath
*/
public void breath()
{
System.out.println("hu...hu...");
}
private int height;
}
The definition of the derived class Woman class and its construction method:
Copy the code code as follows:
class Woman extends Human
{
/**
* constructor
*/
public Woman(int h)
{
super(h); // base class constructor
System.out.println("Hello, Pandora!");
}
/**
* new method
*/
public Human giveBirth()
{
System.out.println("Give birth");
return (new Human(20));
}
/**
* override Human.breath()
*/
public void breath()
{
super.breath();
System.out.println("su...");
}
}
Summarize
extends
method overriding
protected
super.member, super()