There is a saying in "Think in Java": Code reuse is one of the many eye-catching features of Java. But for a language to be highly revolutionary, it's not just enough to be able to copy code and change it; it must be able to do more. The most eye-catching thing in this sentence is "reuse code". Reusing code as much as possible is what we programmers have been pursuing. Now I will introduce a way to reuse code, which is also one of the three major characteristics of Java. One---Inheritance.
Inheritance
Before explaining, let’s take a look at an example. This example is from the previous blog post (Java Improvement - Understanding the Encapsulation of the Three Major Characteristics of Java).
From here we can see that the Wife and Husband classes are all the same except for their respective husbands and wives. As a programmer who wants to maximize code reuse We can't stand such repeated code. If there is another Xiaosan, Xiaosi, Xiaowu... (I'm going too far), do we have to write it like this? So how do we make these classes reusable? Take advantage of inheritance! !
First of all, let’s leave the world of software programming. From common sense, we know that husbands, wives, mistresses, mistresses... they are all human beings, and they all have some things in common, such as name, age, gender, head, etc. , and they are all able to eat, walk, talk and other common behaviors, so from here we can find that they all possess human attributes and behaviors, and they also inherit these attributes and behaviors from humans.
From the above we can basically understand the concept of inheritance. Inheritance is a technology that uses the definition of an existing class as a basis to create a new class. The definition of a new class can add new data or new functions. You can also use the functions of the parent class, but you cannot selectively inherit the parent class. By using inheritance, we can reuse previous code very conveniently, which can greatly improve development efficiency.
After using inheritance for Wife and Husband, in addition to reducing the amount of code, we can also clearly see their relationship.
Inheritance describes the "is-a" relationship. If there are two objects A and B, if it can be described as "A is B", it can mean that A inherits B, and B is inherited. The successor is called the parent class or super class, and the successor is called the subclass or derived class.
In fact, the successor is a specialization of the inheritor. In addition to the characteristics of the inheritor, it also has its own unique characteristics. For example, cats have characteristics that other animals do not have, such as catching mice and climbing trees. At the same time, in the inheritance relationship, the inheritor can completely replace the inherited, but not vice versa. For example, we can say that a cat is an animal, but we cannot say that the animal is a cat. This is actually the reason why we call this "upward transformation". ”, introduced below.
It is true that inheritance defines how classes relate to each other and share characteristics. For several identical or familiar classes, we can abstract their common behaviors or attributes and define them as a parent class or super class, and then use these classes to inherit the parent class. They can not only have the properties and methods of the parent class You can also define your own unique properties or methods.
At the same time, you need to remember three sentences when using inheritance:
1. The subclass has the non-private properties and methods of the parent class.
2. Subclasses can have their own attributes and methods, that is, subclasses can extend parent classes.
3. Subclasses can implement the methods of the parent class in their own way. (Introduced later).
In summary, using inheritance does have many advantages. In addition to putting the common attributes of all subclasses into the parent class to achieve code sharing and avoid duplication, it can also modify and extend the inherited implementation. easier.
It is true that when it comes to inheritance, these three things are indispensable: constructor, protected keyword, and upward transformation.
Constructor
We know from the above that subclasses can inherit the properties and methods of the parent class. In addition to those private ones, there is another thing that subclasses cannot inherit---the constructor. As for the constructor, it can only be called and cannot be inherited. To call the constructor of the parent class, we can use super().
For subclasses, the correct initialization of its constructor is very important, and if and only if there is only one method that can ensure this: calling the parent class constructor in the constructor to complete the initialization, and the parent The class constructor has all the knowledge and capabilities needed to perform initialization of the parent class.
public class Person { protected String name; protected int age; protected String sex; Person(){ System.out.println("Person Constrctor..."); } } public class Husband extends Person{ private Wife wife; Husband(){ System.out.println("Husband Constructor..."); } public static void main(String[] args) { Husband husband = new Husband(); } } Output: Person Constrctor... Husband Constructor...
It can be seen from this example that the construction process spreads "outward" from the parent class, that is, starting from the parent class and completing the construction step by step to the subclass. And we did not explicitly reference the constructor of the parent class. This is the cleverness of Java: the compiler will call the constructor of the parent class for the subclass by default.
However, this default call to the constructor of the parent class is predicated: the parent class has a default constructor. If the parent class does not have a default constructor, we must explicitly use super() to call the parent class constructor, otherwise the compiler will report an error: A constructor that conforms to the form of the parent class cannot be found.
public class Person { protected String name; protected int age; protected String sex; Person(String name){ System.out.println("Person Constrctor-----" + name); } } public class Husband extends Person{ private Wife wife; Husband(){ super("chenssy"); System.out.println("Husband Constructor..."); } public static void main(String[] args) { Husband husband = new Husband(); } } Output: Person Constrctor-----chenssy Husband Constructor...
So to sum up: For inheritance, the subclass will call the parent class's constructor by default, but if there is no default parent class constructor, the subclass must explicitly specify the parent class's constructor. , and must be the first thing done in the subclass constructor (the first line of code).
protected keyword
The private access modifier is the best choice for encapsulation, but this is only based on an ideal world. Sometimes we need this Need: We need to hide certain things from the world as much as possible, but still allow members of subclasses to access them. At this time you need to use protected.
For protected, it indicates that as far as the class user is concerned, it is private, but for any subclass that inherits this class or any other class located in the same package, it is private accessible.
public class Person { private String name; private int age; private String sex; protected String getName() { return name; } protected void setName(String name) { this.name = name; } public String toString(){ return "this name is " + name; } /** 省略其他setter、getter方法 **/ } public class Husband extends Person{ private Wife wife; public String toString(){ setName("chenssy"); //调用父类的setName(); return super.toString(); //调用父类的toString()方法 } public static void main(String[] args) { Husband husband = new Husband(); System.out.println(husband.toString()); } } Output: this name is chenssy
From the above example, you can see that the subclass Husband can obviously call the setName() of the parent class Person.
It is true that although you can use the protected access modifier to limit access to parent class properties and methods, the best way is to keep the properties private (we should always keep changes to the underlying implementation) and use the protected method to Controls access permissions for inheritors of a class.
public class Person { public void display(){ System.out.println("Play Person..."); } static void display(Person person){ person.display(); } } public class Husband extends Person{ public static void main(String[] args) { Husband husband = new Husband(); Person.display(husband); //向上转型 } }
So when we use inheritance, we need to make sure that using inheritance is indeed an effective and feasible method. So should we use inheritance? "Think in Java" provides a solution: ask yourself whether you need to make an upward transformation from the subclass to the parent class. If upward transformation is necessary, inheritance is necessary, but if not, you should carefully consider whether you need inheritance.
Use inheritance with caution! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !
The above is the Java Improvement Chapter (2) ----- Understanding the inheritance of the three major characteristics of Java. For more related content, please pay attention to the PHP Chinese website (m.sbmmt.com)!