What is inheritance?
Inheritance is also one of the important features of object-oriented. As the name implies, inheritance refers to the action of deriving a new class from an existing class. New classes can absorb existing classes of data properties and behaviors, and can extend new capabilities.
In layman's terms, it means that Java can derive new classes from existing classes in a way that inherits. The existing class is called a superclass (the parent class), and the new class that is derived is called a subclass (derived class).
First, subclasses access all non-private methods and member variables that inherit the superclass, and second, you can add new methods and fields based on the original members of the parent class, or overwrite (override) The methods of the parent class.
All too often this is said: The parent class is the generalized representation of the subclass, and the subclass is the characteristic representation of the parent class.
The use of the keyword "extends" in Java is used to declare that a class inherits from another class.
The embodiment of inheritance
First, suppose we customize an employee class "employee":
Package Com.tsr.j2seoverstudy.extends_demo;public class Employee {private String name;//name private int salary;//Income Publi C String GetName () {return name;} public void SetName (String name) {this.name = name;} public int getsalary () {return salary;} public void setsalary (int salary) {this.salary = salary;}}
in a department, employees are usually divided into managers and ordinary employees. Most of them behave similarly, but may vary slightly in income.
Assuming that the average employee's income is paid, the manager's income structure is constructed from the salary + performance bonus. So this time, the original employee class is not enough to describe the manager.
Thus, using inheritance derives from the original employee Class A new manager class "manager":
Package Com.tsr.j2seoverstudy.extends_demo;public class Manager extends Employee {//subclass new Unique instance domain: Performance bonus private int bonus; public int Getbonus () {return bonus;} public void Setbonus (int bonus) {this.bonus = bonus;}}
Inherited attributes
1. Subclasses inherit the methods in the superclass and the instance fields
Package Com.tsr.j2seoverstudy.extends_demo;public class Javaextendsdemo {public static void main (string[] args) { Manager m = new manager (); M.setname ("manager Zhang"); System.out.println (M.getname ()); M.setbonus (20000); System.out.println (M.getbonus ());}}
As you can see here, we do not define the member variable "name" in the derived class "Manager", nor do we define its associated Set/get method.
But we can still access these members through the "Manager" class, just because of the inheritance mechanism.
"Manager" inherits from the "Employee" class, so all non-privatized members of the "Emoloyee" class are implicitly inherited to the subclass "manager".
2. Method Overwrite (override)
As we have said earlier, the manager's income structure is: Salary + bonus. Therefore, the "employee" category of the method of obtaining employee income "getsalary" does not apply to describe the manager's income.
For the "Manager" class, the value returned by the "getsalary" method should be: Salary + bonus. It involves an important point of knowledge in inheritance: Method Overwrite (override)
Overwrite means that all declarations of a method, except the method body, are the same as in the parent class, and the access modifier of the method is only more lenient than the parent class.
Be sure to keep in mind the rules that are covered before you can use them again without error. The following is an online view of 's face test, to more visually understand the concept of the overwrite:
Package com.tsr.j2seoverstudy.extends_demo;/* * QUESTION no:3. Class A {*. protected int method1 (int A, int b) {return 0;} . } * * which-valid in a class that extends Class A? (Choose) * A. public int method1 (int A, int b) {return 0;} * B. private int method1 (int a, int B) {return 0;} * C. private int method1 (int A, long b) {return 0;} * D. Public short method1 (int a, int b) {return 0;} * E. Static protected int method1 (int a, int b) {return 0;} */public class Test {}class a {protected int method1 (int A, int b) {return 0;}} Class B extends A {//Legal, to override the parent class method by increasing access rights (Protected→public). public int method1 (int a, int b) {return 0;} Illegal, note the overwrite rule: the access modifier for a method can be more lenient than the parent class. private int method1 (int a, int b) {return 0;} Legal, but not method overwrite. Instead of just in class B, the inherited method Method1 is overloaded; private int method1 (int A, long b) {return 0;} Illegal, the first method return type cannot be used as an indication of the method overload. Then it is only the case of the overwrite, but the overwrite requirement: Except for the method body, all declarations of the method are the same as in the parent class. public short method1 (int a, int b) {return 0;} is not legal, also because the method declaration differs from the parent class. Staticprotected int method1 (int a, int b) {return 0;}}
3. Reference the parent keyword "Super"
As we said in the 2nd feature, for the "Manager" class, the value returned by the "getsalary" method should be: Salary + bonus. in other words, "getsalary" should be implemented in the "Manager" class:
public int getsalary () {return bonus + salary; }
In practice, however, this must not work because salary is declared private in the parent class. Therefore, it is not possible to access directly in a subclass.
Therefore, we can only get its value through the parent class, which provides the access method "Getsalary" for that member variable. So maybe the correct implementation should be:
@Overridepublic int getsalary () {return getsalary () + bonus;}
But since we have already covered the method with new requirements, all this is not feasible.
This is because, by way of overwrite, the "Employee" class has its own unique "getsalary" method, so the above practice is to let "getsalary" constantly call itself, until the program crashes.
To call a member of the parent class, you can use one of the Java keywords: super.
Super is a special keyword that is provided by Java for just the compiler to call a superclass member. So the modified "getsalary" method should be:
@Overridepublic int getsalary () {return super.getsalary () + bonus;}
4. Polymorphism and dynamic binding
polymorphism refers to the ability of the same thing to use different definitions depending on the context. For example, we are familiar with the overloaded, overwrite is a manifestation of polymorphism. Polymorphism is another important feature of object-oriented.
The embodiment of polymorphism in Java inherits from the following main forms, namely:
- Polymorphism of objects : For example, we define a super-class animal "Animal", in which tigers "tiger" and "fish" are inherited from "Animal". This is the polymorphic embodiment of the object of a class. Because an animal (Animal) Constructs an object that can be either a tiger "tiger" or "fish".
- Polymorphism of the method : Suppose that the animal class "Animal" provides an animal breathing method "breath". But because tigers and fish breathe differently, tigers breathe with their lungs, and fish breathe through their gills. So we need to overwrite the "breath" method in the corresponding subclass respectively. This is also a manifestation of the polymorphic form of the method.
Dynamic binding means that a program is bound to a specific type of object at run time (not at compile time), so it is called runtime binding. The execution of dynamic bindings is probably:
1, first, The compiler first looks at and obtains the declaration type and method name of the object;
Then the corresponding class of its declaration type and the method table of its superclass are searched;
Finally, the method that all methods are declared as "pulbic" is searched for the corresponding method names, and all possible candidate methods are obtained.
Note: The method table means that when a class is first run and loaded by a class loader (ClassLoader), all the method information of itself and its superclass is loaded into the in-memory method area.
2. The compiler looks at the type of arguments passed in when the method is called.
If there is a full compliance with the supplied parameter type in all the candidate methods obtained in the first step of the operation, the binding is determined to call the method.
This process is called overload resolution . It is also possible to understand that the dynamic binding parsing is done by overloading the polymorphic behavior.
In addition, this step can be complicated because Java allows type conversions.
If no method matching the parameter type is found, or if there are multiple matching methods after the type conversion, a compilation error is reported.
Note: Method name + Parameter list = method signature. So the override rules for the method we talked about earlier can also be understood as: The method signature must be the same as the parent class, and the access modifier can be more lenient.
However, it is important to note that the method return type is not part of the method signature. Before JDK1.5, the return type must be the same when the overwrite is required.
In later versions, Overwrite allows the subclass of the parent class return type as the return type, which is called the covariant return type .
3, corresponding to: if it is declared as private, static, final method or constructor, the compiler will be able to directly know exactly how the method should be called. This approach is also known as static binding.
4, if the use of dynamic binding way. When the program runs, it is certain that the object reference is the most appropriate method of the type to which the actual object is pointing.
This is also why in inheritance, subclasses overwrite methods in the superclass. If the type of the superclass is declared, and the object reference to the object that actually references the subclass is called, the method is called exactly to the cause of the post-overwrite method in the child class.
Package Com.tsr.j2seoverstudy.extends_demo;public class Test {public static void main (string[] args) {Animal [] animals = New Animal[3];animals[0] = new Animal (); animals[1] = new Tiger (); animals[2] = new Fish (); for (Animal animal:animals) {A Imal.breath ();}}} Class Animal{void Breath () {System.out.println ("Animal Breath");}} Class Tiger extends animal{@Overridevoid breath () {System.<span style= "font-size:12px;" >out</span>.println ("Tiger breathes with Lungs");}} Class Fish extends animal{@Overridevoid breath () {System.out.println ("Fish with gills Breathing");}} /* The result is: animal breathing tiger breathing fish with gills * *
5. Inheritance structure: Single inheritance and multiple inheritance
Multiple inheritance is not supported in Java. Its inheritance structure is divided into: single inheritance and multiple inheritance.
As the name implies, single inheritance means that a class can inherit from only one superclass.
Multiple inheritance means that Class C inherits from Class B, whereas Class B inherits from an inheritance hierarchy such as Class A.
The application of multiple inheritance is very common. Or animals, for example, tigers inherit from animals. And tigers may be divided into a variety of Siberian tigers, so the new definition of the Amur tigers should inherit the Tiger class.
This is one of the common manifestations of multiple inheritance.
6. The construction process of the neutron class of the inheriting system
Package Com.tsr.j2seoverstudy.extends_demo;public class Javaextendsdemo {public static void Main (string[] args) { C6/>son s = new Son ();}} Class Far{far () {System.out.println ("Parent class construction Initialization:");}} Class Son extends Far{son () {//There is an implicit construct statement here: Super (), calling the construction initialization work of the parent class. System.out.println ("Subclass construct initialization:");}} /* The result is: The parent class constructs the initialization. Subclass Construction Initialization: */
In other words, the construction of a subclass is dependent on the parent class, and the object construction of the superclass to which it belongs is completed before the construction of the subclass begins.
This is rightfully because we already know that many of the subclasses ' properties and methods are dependent on the parent class, and if you do not first complete the construction of the parent class, the use of subclasses can easily cause errors.
When do I use inheritance?
To understand what uses inheritance, we should first know what the benefits of using inheritance are:
- By inheriting the system, we can make the program more clear.
- In the case of special needs, subclasses can easily change the implementation of the parent class.
- The greatest advantage is that it facilitates the reuse of code and reduces the coding effort.
So, when is the longest time to use inheritance?
1. The famous "is-a" relationship
For example, the "manager is an employee" mentioned above, "Tiger is an animal" belongs to this kind of relationship.
2, want to achieve polymorphism through inheritance
A better understanding of a piece of code, if our program provides an interface for getting the animal's run speed:
int GetSpeed (Animal Animal) { return animal.getrunspeed (); }
Through inheritance, through such simple code. As long as the type of the passed Parameter object is in the inheritance system of the animal, it is possible to obtain its run speed correctly through the mechanism of dynamic binding.
This is actually an embodiment of the "strategy design pattern". If you assume that you do not use inheritance, you need to provide a corresponding number of methods to get the speed of different animals to run separately.
But at the same time, inheritance has some drawbacks:
- Class inheritance is statically defined at compile time, so the implementation of inheriting classes cannot be changed at run time.
- The reuse by inheritance is called "white box reuse" because the implementation details of the parent class are visible to the child class.
- The parent class usually defines at least part of the behavior of the subclass, so changes to the parent class can affect the use of subclasses.
So, as there are two sides to anything in this world, the use of inheritance should be the most appropriate decision for the actual situation.
Kind-Analysis of Java inheritance and dynamic binding