Test with a knife and fly with a stupid bird

Source: Internet
Author: User
Tags class manager what inheritance java keywords

Test with a knife and fly with a stupid bird

What is inheritance?

Inheritance is also an important feature of object-oriented. As the name implies, Inheritance refers to the action that derives a new class from an existing class. New classes can absorb the data attributes and behaviors of existing classes and expand new capabilities.


In other words, Java can derive a new class from an existing class by means of inheritance. This existing class is called a superclass (parent class), and the derived new class is called a subclass (derived class ).

First, subclass access inherits all non-private methods and member variables in the superclass. Second, you can add some new methods and fields based on the original members of the parent class, or override the method of the parent class ).


In general, the parent class is a general manifestation of the Child class, and the Child class is a special manifestation of the parent class.


In Java, the keyword "extends" is used to declare that one class inherits from another class.


Embodiment of Inheritance

First, assume that we have customized an Employee class "Employee ":

Package com. tsr. j2seoverstudy. extends_demo; public class Employee {private String name; // name private int salary; // Income public 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 generally divided into managers and General Employees. Most of the behaviors between the two are similar, but may be slightly different in terms of income.

Assume that the income source of an ordinary employee is salary, while the manager's income structure is constructed by salary + performance bonus. At this time, the original employee class was not enough to describe the manager.

As a result, inheritance is used to generate a new Manager class "Manager" from the original employee class ":

Package com. tsr. j2seoverstudy. extends_demo; public class Manager extends Employee {// subclass new special instance domain: performance bonus private int bonus; public int getBonus () {return bonus;} public void setBonus (int bonus) {this. bonus = bonus ;}}


Inherited features

1. The subclass inherits the methods in the superclass and the instance domain

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 ());}}

Here we can see that the "Manager" of the derived class does not define the member variable "name" or its related set/get method.

However, we can still access these members through the "Manager" class because of the Inheritance Mechanism.

"Manager" is inherited from the "Employee" class, so all non-private members of the "Emoloyee" class are implicitly inherited to the sub-class "Manager.


2. override)

As we have already said before, the manager's income structure is: salary + bonus. Therefore, the "getSalary" method for obtaining Employee income in the "Employee" category is not suitable for describing the manager's income.

For the "Manager" class, the value returned by the "getSalary" method should be salary + bonus. At this time, it involves an important point of inheritance: override)

Override means that, except for the method body, all declarations of the method should be the same as those in the parent class, and the access modifier of the method can only be more loose than the parent class.


You must remember the overwriting rules to avoid errors when using them. The following is an interview question about Huawei, which we can see on the Internet, to better understand the concept of overwriting:

Package com. tsr. j2seoverstudy. extends_demo;/** question no: 3*1. class A {* 2. protected int method1 (int a, int B) {return 0;} * 3 .} ** Which two are valid in a class that extends class? (Choose two) *. 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 {// valid, by increasing Access Permissions (Protected → public) to override the parent class method. Public int method1 (int a, int B) {return 0 ;}// invalid. Note the overwriting rule: the access modifier of the method can only be looser than the parent class. Private int method1 (int a, int B) {return 0 ;}// valid, but not method override. In Class B, the inherited method method1 is overloaded. private int method1 (int a, long B) {return 0 ;}// is invalid, first, the return type of the method cannot be used as an identifier for method overloading. The method can only be overwritten, but the overwriting requirements: Except for the method in vitro, all the declarations of the method are the same as those in the parent class. Public short method1 (int a, int B) {return 0;} // invalid. It is also because the method declaration is different from the parent class. Static protected int method1 (int a, int B) {return 0 ;}}


3. reference the parent keyword "super"

We mentioned in the 2nd point feature that for the "Manager" class, the value returned by the "getSalary" method should be salary + bonus. That is to say, in the "Manager" class, the implementation of "getSalary" should be:

public int getSalary(){return bonus + salary;             }
But in fact, this is definitely not feasible because salary is declared as private in the parent class. Therefore, the sub-classes cannot be accessed directly.

Therefore, we can only get its value through the access method "getSalary" provided for this member variable in the parent class. Therefore, the correct implementation may be:

@Overridepublic int getSalary() {return getSalary() + bonus;}
However, because we have already overwritten this method based on new requirements, it will not work.

This is because through method overwriting, the "Employee" class already has its own unique "getSalary" method, so the above practice is actually allowing "getSalary" to continuously call itself, until the program crashes.


To call a member in the parent class, you can use one of the Java keywords: super.

Super is a special keyword provided by Java for the compiler to call super class members. Therefore, the modified "getSalary" method should be:

@Overridepublic int getSalary() {return super.getSalary() + bonus;}


4. polymorphism and dynamic binding

PolymorphismIt refers to the ability of a thing to use different definitions according to different context environments. For example, the familiar overload and overwrite operations are a manifestation of polymorphism. Polymorphism is another important feature of object orientation.

The embodiment of polymorphism in Java is as follows:

  • Object polymorphism: for example, we define a super Animal "Animal", where both the Tiger class "Tiger" and the Fish "Fish" inherit from "Animal ". This is a manifestation of the polymorphism of a type of objects. Because the object constructed by an Animal can be either a Tiger "Tiger" or a Fish ".
  • Method polymorphism: Assuming the Animal "Animal" provides an Animal breathing method "Breath ". However, because tigers and fish breathe differently, tigers breathe through their lungs, while fish breathe through their heads. Therefore, we need to override the "Breath" method in the corresponding subclass. This is also a manifestation of method polymorphism.

Dynamic bindingIt means that the program is bound according to the specific type of the object during the runtime (rather than the compilation period), so it is also called runtime binding. The execution process of dynamic binding is roughly as follows:

1. First, the compiler first checks and obtains the object declaration type and method name;

Find the corresponding classes and their superclasses in the method table corresponding to their declared types;

Finally, the method with the corresponding method name declared as "pulbic" is searched to obtain all candidate methods that may be executed.


Note: The method table means that when a class is first run and loaded by the class loader (classloader, all method information of itself and its superclasses will be loaded into the method area in the memory.


2. the compiler will view the type of parameters passed in when calling a method.

If one of all the candidate methods obtained in the first step fully matches the provided parameter type, the binding will decide to call the method.

This process is calledReload Parsing. It can be understood that the dynamic binding parsing of the polymorphism manifested by heavy loads is done in this way.

In addition, this step may be complicated because Java allows type conversion.

If the method that matches the parameter type is not found, or there are multiple matching methods after the type conversion, a compilation error is reported.


Note: method name + parameter list = method signature. The method overwrite rules we mentioned earlier can also be understood as: The method signature must be the same as the parent class, and the access modifier can only be loose.

However, it is worth noting that the method return type is not part of the method signature. Before JDK1.5, the return type must be the same for overwriting.

In Versions later than this, overwriting allows subclass of the return type of the parent class to be used as the return type, which is calledCovariant return type.


3. Corresponding: if it is declared as a private, static, final method or constructor, the compiler can directly and accurately know the method to be called. This method is also called static binding.


4. If dynamic binding is used. When running the program, you must select the most appropriate method of the actual object type pointed to by the object reference.

This is why the subclass overwrites the methods in the superclass in inheritance. If the super class type is used for declaration, and the object of the object that actually references the subclass references the calling method, the reason for accurately calling the method after overwriting In the subclass is returned.

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) {animal. breath () ;}} class Animal {void breath () {System. out. println ("Animal breathing");} class Tiger extends Animal {@ overrisponid breath () {System. <span style = "font-size: 12px;"> out </span>. println ("Tiger breathing with lung");} class Fish extends Animal {@ overrisponid breath () {System. out. println ("fish with cheek breathing");}/* running result: Animal breathing tiger breathing fish with cheek breathing */

5. Inheritance structure: single inheritance and multi-Inheritance

Java does not support multi-inheritance. Its Inheritance structure includes single inheritance and multi-inheritance.

As the name implies, single inheritance means that a class can only inherit from one super class.

Multi-inheritance means that class C inherits from Class B, while Class B inherits from the hierarchy of Class.

Multi-inheritance applications are common. Take animals as an example. Tigers inherit automatic things. Tigers may be divided into many different types, such as northeast tigers. Therefore, the newly defined northeast Tigers should inherit from the Tigers.

This is a common embodiment of Multi-inheritance.


6. Inheritance System subclass Construction Process

Package com. tsr. j2seoverstudy. extends_demo; public class JavaExtendsDemo {public static void main (String [] args) {Son s = new Son () ;}} class Far {Far () {System. out. println ("parent class construction initialization .. ") ;}} class Son extends Far {Son () {// here is an implicit construction statement: super (), which calls the construction initialization of the parent class .. system. out. println ("subclass construction initialization .. ") ;}}/* run the result: parent class construction initialization .. subclass construction initialization .. */
That is to say, the constructor of a subclass depends on its parent class. Before starting the constructor of a subclass, the constructor of the superclass is completed.

This is justified, because we already know that many attributes and methods of sub-classes depend on the parent class. If the construction of the parent class is not completed before, the use of subclass can easily cause errors.


When to use inheritance?

To understand what inheritance can be used, we should first know the benefits of inheritance:

  • The inheritance system makes the program more rational.
  • If special requirements occur, subclass can easily modify the implementation of the parent class.
  • The biggest benefit is that it facilitates code reuse and reduces coding work.

So when should inheritance be used at most?

1. The famous "IS-A" Relationship

For example, the manager is an employee, and the tiger is an animal.

2. Implement polymorphism through inheritance

To better understand a piece of code, assume that our program provides an interface to get the running speed of animals:

    int getSpeed(Animal animal){    return animal.getRunSpeed();    }
Through inheritance, through such simple code. As long as the input parameter object type is in the Animal inheritance system, you can get its running speed through the dynamic binding mechanism.

This is actually a reflection of the "policy design model. If inheritance is not used, a corresponding number of methods are required to obtain the running speeds of different animals.


At the same time, inheritance also has some drawbacks:

  • Class inheritance is statically defined at the time of compilation, so the implementation of the inheritance class cannot be changed at runtime.
  • The inherited reuse method 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 some behavior of the Child class, so changes to the parent class may affect the usage of the Child class.

Therefore, just as everything in this world has two sides, we should make the most appropriate decision on the use of inheritance based on the actual situation.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.