Abstract:Inheritance is a concept in object-oriented software technology. It makes it very easy to reuse old code, which can greatly shorten development cycles and reduce development costs.

This article is shared from Huawei cloud community “the most aunt Java inheritance in the history of” swastika text and text “by Bigsai.

Course of learning

In Java class, all teachers have to mention Object Oriented, and when talking about Object Oriented, they have to mention the three characteristics of Object Oriented: encapsulation, inheritance and polymorphism. The three characteristics are closely related but different, and this course will take you to learn Java inheritance.

You may not know exactly what inheritance is for, but chances are you’ve been doing a lot of repetitive work on a Java project/assignment, creating a lot of similar classes with a lot of the same methods, and feeling bloated. Properly using inheritance can greatly reduce duplication of code,Improve code reusability.

The first acquaintance of inheritance

To learn inheritance, we must first understand what inheritance is and its function from a broad concept, and then learn the specific implementation details of inheritance from a detailed aspect. This article is to take you to quickly understand and understand the important concept of inheritance.

What is inheritance

Inheritance (English: inheritance) is a concept in object-oriented software technology. It makes it very easy to reuse old code, which can greatly shorten development cycles and reduce development costs.

Java language is a very typical object-oriented language. In Java language, inheritance means that a subclass inherits the attributes and methods of its parent class, so that the object (instance) of a subclass has the attributes and methods of its parent class, or a subclass inherits methods from its parent class, so that the subclass has the same methods of its parent class. A superclass is sometimes called a base class or a superclass. A subclass is sometimes called a derived class.

To throw one’s hat in the ring to throw one’s hat in the ring To throw one’s hat in the ring To throw one’s hat in the ring Among the kinds of animals, we are familiar with cats, dogs and other animals. They all have the general characteristics of animals (such as being able to eat and make sounds), but they are different in details (different animals eat differently and make different noises). When implementing classes like Cat and Dog in the Java language, you need to inherit Animal. After inheritance, specific Animal classes such as Cat and Dog are subclasses, while Animal class is the parent class.

Why you need inheritance

You might wonder why you need inheritance? When it comes to implementation, we just implement the methods when we create a class like Dog, Cat, etc. Implement this inheritance seems to make the structure of the class less clear.

If there are only two or three classes and each class has limited properties and methods, there is no need to implement inheritance, but that is not the case. In fact, there are often many classes in a system with many similarities. For example, cats and dogs are animals, or students and teachers are people. Each class may have many of the same properties and methods, so if each class were to be rewritten, not only would the code be messy, but the code would be a lot of work.

At this point, the advantages of inheritance come out: you can directly use the properties and methods of the parent class, you can also have your own new properties and methods to meet the expansion, and the methods of the parent class can also be overwritten if you have needs to change.Using inheritance in this way not only greatly reduces the amount of code, but also makes the code structure more visible.

So from a code level we designed the complete Animal class like this:

class Animal { public int id; public String name; public int age; public int weight; public Animal(int id, String name, int age, int weight) { this.id = id; this.name = name; this.age = age; this.weight = weight; Public void sayHello() {System.out.println("hello");} public void sayHello() {System.out.println("hello"); } public void eat() { System.out.println("I'm eating"); } public void sing() { System.out.println("sing"); }}

Dog, Cat, and Chicken can be designed like this:

Class Dog extends Animal {public Dog(int id, String name, int age, int weight) {super(id, name, age, int weight) {public Dog(int id, String name, int age, int weight) {super(id, name, age, weight); }} class Cat extends Animal{public Cat(int id, String name, int age, int weight) {super(id, name, age, int name, int weight) {super(id, name, age, int name, int weight, int weight) {super(id, name, age, int weight); weight); } class Chicken extends Animal{public Chicken(int id, String name, int age, int weight) {super(id, name, int weight) {public Chicken(int id, String name, int age, int weight) {super(id, name, int weight); age, weight); } public void layEggs() {System.out.println();} public void layEggs() {System.out.println(); Cluck cluck!" ); }}

Each class inherits from Animal and can use the properties and methods of Animal directly without having to write them again. Each class can easily extend its own methods if it has its own methods. Notice in the code above that extends is used to implement inheritance.

Classification of inheritance

Inheritance can be divided into single inheritance and multiple inheritance. Java language only supports single inheritance of classes, but it can achieve the purpose of multiple inheritance by implementing interfaces.Let’s start with a table that Outlines the differences between the two, and then go into more detail.

Single inheritance

Single inheritance is a subclass that has only one parent, like the Animal class and its subclasses we talked about above. Single inheritance is clearer in the class hierarchy, but the disadvantage is that the richness of the structure is sometimes not sufficient for use.

Multiple inheritance (not supported in Java, but possible)

Multiple inheritance is a subclass that has multiple immediate superclasses. The advantage of this is that subclasses have all the characteristics of their parent classes and are very rich, but the disadvantage is that they can be confusing. Below is an example of a mess.

Java does not support multiple inheritance, but Java has three ways to achieve the effect of multiple inheritance: inner classes, multi-layer inheritance, and implementation interfaces.

The inner class can inherit a class independent of the outer class, ensuring the independence of the inner class. It is based on this point that the effect of multiple inheritance can be achieved.

Multi-level inheritance: a subclass inherits from its parent class. If the parent class inherits from other classes, this is called multi-level inheritance. The subclass will then own all the properties and methods of the inherited class.

Implementing an interfaceThis is undoubtedly the best way to meet the needs of multiple inheritance usage. A class can implement multiple interfaces to meet its own usage needs in rich and complex environments. Class versus interface,Whereas a class is an entity with properties and methods, an interface is more like a set of methods. For example, take the Douro mainland Tang three, his existence of the inheritance relationship may be like this:

How to implement inheritance

In addition to the extends used above, implementation inheritance can be implemented with the keyword implements. Now let me explain them to you one by one.

The extends keyword

In Java, class inheritance is single, meaning that a child class can have only one parent class, so extends can inherit only one class. Its usage syntax is:

Class extends superclass {} For example, the Dog class extends the Animal class. It looks like this:

Class Dog extends Animal{} class Dog extends Animal{

When a subclass inherits from the parent class, it has the nonprivate properties and methods of the parent class. If you don’t understand, take a look at this example. Create a project under Idea, create a Test class to test, respectively create Animal class and Dog class, Animal as the parent class write a SayHello () method, Dog class inherited from Animal class can call SayHello () method. The specific code is:

Public void sayHello() {System.out.println(" Hello, Everybody "); }} public class test {public static void main(String[] args) {Dog Dog =new Dog(); dog.sayHello(); }}

When you click Run, the Dog subclass can use the methods of the Animal superclass directly.

The implements keyword

Using the implements keyword allows Java to have multiple inheritance, and in the case of a class implementing interfaces, a class can implement more than one interface (separated by a comma). A Java interface is a series of method declarations; there is no concrete implementation of the method in an interface. When a subclass implements an interface, it must override methods in the interface.

Let’s look at an example of creating a Test2 class to test, creating the DOA interface and the DOB interface respectively. The DOA interface declares the sayHello() method, the DOB interface declares the eat() method, and the Cat2 class implements the DOA and DOB interfaces. And you need to override the sayHello() and eat() methods in your class. The specific code is:

interface doA{ void sayHello(); } interface doB{ void eat(); Public void eat(){System.out.println("eating"); public void eat(){System.out.println("eating"); } public void sayHello() {System.out.println(" Hello!");} public void sayHello() {System.out.println(" Hello!");} public void sayHello() {System.out.println(" Hello!"); ); } @Override public void eat() { System.out.println("I'm eating"); } } public class test2 { public static void main(String[] args) { Cat2 cat=new Cat2(); cat.sayHello(); cat.eat(); }}

When the Cat class implements DOA and DOB interfaces, it needs to implement its declared methods. Click “Run” and the result is as follows. This is a simple case of a class implementing interfaces:

Characteristics of inheritance

The main content of inheritance is that the subclass inherits from the superclass and overwrites the methods of the superclass. When we use a property or method of a child class, we first need to create an object, and the object is created by a constructor. In the constructor, we may call some properties and methods of the child class, so we need to know the this and super keywords in advance. After the object is created, call the method that overrides the parent class and distinguish the difference between overriding and overloading. So this section describes the order in which this, super – > constructors – > method overrides – > method overrides.

This and super keywords

The “this” and “super” keywords are very important in inheritance. They represent a reference to the current object and a reference to the superclass object, respectively. They are very similar but have some differences.

This represents the current object and is a reference to itself.

() // Calling one of the class methods this() // means calling the constructor of the class

Super represents the superclass object and is a reference to the superclass.

The super. Property // represents the super member variable in the superclass object. The method () // represents a method defined in the superclass object super() // calls the superclass constructor

In addition, the this and super keywords can only appear in code that is not static decorated.

Both this() and super() can only appear on the first line of the constructor. If this() is used to call another constructor of the current class, and super() is used to call a constructor of the parent class, both can choose one or the other according to their own usage requirements.

Write a small case to create class D1 and subclass D2 as follows:

Public void sayHello() {System.out.println("hello"); public void sayHello() {System.out.println("hello"); } } class D2 extends D1{ public String name; public D2(){ super(); // Call the superclass constructor this.name="BigSai"; Public void sayHello() {System.out.println(" Hello, I am "+this.name);} public void sayHello() {System.out.println(" Hello, I am "+this.name); } public void test() { super.sayHello(); // Call the superclass method this.sayHello(); } public class test8 {public static void main(String[] args) {D2 D2 =new D2(); d2.test(); }}

The result of execution is:

A constructor

A constructor is a special method that is a method with the same name as a class. Object creation is accomplished through the constructor, whose main function is to complete the initialization of the object. But in the inheritance of the construction method is a relatively special method (such as can not inherit), so to understand and learn the rules and requirements of the construction method in inheritance.

Constructors can be divided into parameter construction and no-parameter construction, which can be reasonably set according to their own use requirements. Constructors in inheritance have the following caveats:

The constructor of the parent class cannot be inherited:

Because the constructor syntax has the same name as the class, and inheritance does not change the method name, if a subclass inherits the constructor from its parent class, it obviously conflicts with the constructor syntax. For example, if Son inherits Father() from Father, that would be in conflict with the constructor definition: the constructor does not have the same name as the class, so a child class cannot inherit the parent’s constructor, but the child class will call the parent’s constructor.

The constructor of a subclass must call the constructor of its parent class:

The Java virtual organization constructs the superclass object before the subclass object is constructed, and then constructs the properties specific to the subclass after the superclass object is constructed. This is called memory overlay. The Java virtual constructor object executes the constructor of the parent class, so the subclass constructor must call super(), the constructor of the parent class. For example, a simple inheritance case would be written like this:

class A{ public String name; Public class B extends A{public B() {public A() {public B() {public A(); public A() {public B(); public A(); } public B(String name) {// Super (); super(name); }}

If the parent constructor is not explicitly called in the constructor of the child class, the system calls the parent’s parameter-free constructor by default.

If you don’t believe me, we will automatically add the super() constructor to the superclass. If you don’t believe me, we will modify the above class a little bit:

Method Override

Method overriding is the occurrence of the same method (return type, method name, argument list) in the subclass as in the parent class. It is based on inheritance. You can think of it as the shell of the method unchanged, but the core content is rewritten.

Here is an easy to understand method rewrite case:

Class E1{public void doA(int a){System.out.println(" This is the method of the superclass "); }} class E2 extends E1{@Override public void doA(int a) {System.out.println();}} class E2 extends E1{@Override public void doA(int a) {System.out.println(); }}

The @Override annotation shows that the method is declared as an annotation method, which can help you check the syntactic correctness of the overridden method. If you do not Override the method, it is possible, but it is recommended.

There are a few things you need to keep in mind about rewriting:

From the requirements of rewriting:

  • Overridden methods should be the same as the superclass (including return value type, method name, parameter list).
  • Method overrides exist only between subclasses and superclasses, and can only be overloaded within the same class

From the perspective of access rights:

  • A subclass method cannot reduce the access of a superclass method
  • A subclass method cannot throw more exceptions than a superclass method
  • Private methods of a parent class cannot be overridden by a child class

From a static and non-static perspective:

  • A static method of a parent class cannot be overridden by a child class as a non-static method
  • A subclass can define a static method with the same name as the static method of the superclass, so that the static method of the superclass can be hidden in the subclass (satisfying the overriding constraint).
  • A nonstatic method of a parent class cannot be overridden by a child class as a static method

From both abstract and non-abstract perspectives:

  • An abstract method of a parent class can be overridden by a child class in two ways (implementation and overriding).
  • Nonabstract methods of a parent class can be overridden as abstract methods

Of course, these rules may involve some modifiers, which will be covered in more detail in Level 3.

Method Overloading

If you have two methods with the same method name but different arguments, you can say that one method is an overload of the other. The rules for method overloading are as follows:

  • The overloaded method must change its argument list (the number or type or order of arguments is different).
  • An overloaded method can change the return type
  • An overloaded method can change the access modifier
  • An overloaded method can declare new or broader check exceptions
  • Methods can be overloaded in the same class or in a subclass
  • Overloaded functions cannot be distinguished by the return value type

Overloading can generally be understood as having the same method name to do the same thing, but different parameter lists and other conditions may be different. As a simple example of method overloading, the add() method in class E3 is one of them.

class E3{ public int add(int a,int b){ return a+b; } public double add(double a,double b) { return a+b; } public int add(int a,int b,int c) { return a+b+c; }}

Difference between method overriding and method overloading:

Method overrides and method overrides can be confusing in name, but there are significant differences in content. Here is a table showing the differences:

Inheritance and Modification

Java modifiers role is to modify or limit, class or a class member each modifier has its own role, and there may be some special modifiers in succession make modified properties or methods cannot be inherited, or inheritance need some other conditions, the following is described in detail in succession some function and feature of the modifier.

The Java language provides a number of modifiers that define classes, methods, or variables, usually at the very beginning of a statement. It is mainly divided into the following two categories:

  • Access modifier
  • Non-access modifier

We will focus on the four types of access control modifiers: public, protected, default, and private. The static, final, and abstract modifiers are described here.

Access modifier

Public, protected, default, and private modifiers are important to object-oriented knowledge, and it’s important to know the rules for using modifiers in inheritance.

First of all, we all know that different keywords have different scopes. The scopes of the four keywords are as follows:

  1. Private: The narrowest modifier in the Java language that restricts access permissions, commonly referred to as “private.” Attributes and methods decorated by it are accessible only to objects of the class, not to subclasses, and not to cross-package access.
  2. Default :(also known as friendly) is the absence of any access modifier, often referred to as “Default Access” or “Package Access.” In this mode, access is only allowed within the same package.
  3. Protected: An access modifier between public and private, commonly referred to as “protected access”. Attributes and methods that are decorated by them can only be accessed by methods of the class itself and by subclasses, even if the subclasses are accessible in different packages.
  4. Public: The most restricted-access modifier in the Java language, commonly referred to as “public”. It modifies classes, properties, and methods that can be accessed not only across classes, but also across packages.

When a Java subclass overwrites an inherited method, it cannot reduce the access permission of the method. A subclass that inherits from a parent cannot have a smaller access modifier scope than the parent. If the parent is protected, its subclass can be protected or public. It must not be default or private. So methods that need to be overridden in inheritance cannot be modified with the private modifier.

If this is not clear enough, it is easy to see some examples. If you write a class A1 that implements four methods with four modifiers, then subclass A2 inherits A1, then you can see that the parent private method cannot be overridden, and the non-private method overridden uses a modifier with a smaller scope (greater than or equal to).

The correct example would be:

class A1 { private void doA(){ } void doB(){}//default protected void doC(){} public void doD(){} } class A2 extends A1{ @ Override public void doB () {} / / access modifier to subclassing rewriting method permissions can expand @ Override protected void doC () {} / / to subclassing rewriting method to access modifier permissions and parent class line Public void doD() {}// Not protected or default}

Also note that an exception thrown by a subclass in an inheritance must be either an exception thrown by the parent class or a child of an exception thrown by the parent class. In the following example, a four-method test can find that the exception of a subclass method cannot be greater than the range of the exception thrown by the corresponding parent method.

The correct example would be:

class B1{ public void doA() throws Exception{} public void doB() throws Exception{} public void doC() throws IoException {} public void doD() throws ioException {}} class B2 extends B1{public void doD() throws ioException {} public void doD() throws ioException {} public void doD() throws ioException {} public void doD() throws ioException {}} class B2 extends B1{ Throws IOException {} // Override public void doB() throws IOException {} // Override public void doB() throws IOException {} // Override public void doB() throws IOException {} // Void doD() throws IOException {} @Override public void doD() throws IOException {}}

Non-access modifier

The access modifiers are used to control access, while the non-access modifiers each have their own role. The static, final, and abstract modifiers are described below.

The static modifier

Static means “static” and can be used with variables, methods, and classes. These are called static variables and static methods (also known as class variables and class methods). When static variables or methods are used in a class, they can be accessed directly through the class without creating an object of the class to access the members.

You might want to use static methods when you’re designing classes, and there’s a lot of utility classes like Math, Arrays and so on that have a lot of static methods in them. Static modifier There are many rules for static modifiers. Here are just a few rules for Java inheritance usage:

  • Constructors are not allowed to be declared static.
  • The current object does not exist in the static method, so you cannot use this, and of course you cannot use super.
  • Static methods cannot be overridden by non-static methods.
  • Static methods can be overridden by static methods.

Consider the following examples to prove the above rule:

The source code is:

class C1{ public int a; Public C1(){}// public static C1(){} public static void doA() {} public static void doB() {}} Class C2 extends C1{public static void doC()// There is no current object in a static method, so this and super cannot be used. { //System.out.println(super.a); } public static void doA(){}// static methods can be overridden by static methods // public void doB(){}// static methods can not be overridden by non-static methods}

Final modifier

Final variables:

  • Final means “final”. Once a variable has been assigned, it cannot be reassigned. Instance variables decorated by final must explicitly specify an initial value (that is, they cannot just be declared). Final modifiers are often used in conjunction with static modifiers to create class constants.

The final method:

  • Final methods ina parent class can be inherited by subclasses, but cannot be overridden by subclasses. The main purpose of declaring a final method is to prevent the content of that method from being modified.

Final class:

Final classes cannot be inherited. No class can inherit any of the features of a final class.

Therefore, no matter a variable, method or class is modified by final, it has the meaning of “final” and “final”. The content cannot be modified.

The abstract modifier

Abstract is called “abstract” in English and is used to modify classes and methods, called abstract classes and abstract methods.

Abstract method: there are many different classes of methods are similar, but the concrete content is not very same, so we can only extract his declaration, there is no concrete method body, that is, abstract method can express the concept but can not be implemented.

Abstract classes: Classes with abstract methods must be abstract classes. An abstract class can express concepts but cannot construct entities.

Abstract classes and abstract methods have more content and rules. Just a few usages and rules related to inheritance are mentioned here:

  • An abstract class is also a class. If a class inherits from an abstract class, it cannot inherit from another (class or abstract class).
  • Subclasses can inherit from abstract classes, but must implement all of the abstract methods of the parent class. Subclasses must also be defined as abstract classes if they cannot be fully implemented
  • A complete class is complete only if it implements all of the abstract methods of its parent class.

For example, we could design an abstract People class and an abstract method in a subclass like this:

abstract class People{ public abstract void sayHello(); Public void sayHello() {System.out.println(" Hello ");} public void sayHello() {System.out.println(" Hello "); } class Japanese extends People{@Override public void sayHello() {System.out.println(); } public void sayHello() {System.out.println("hello");} public void sayHello() {System.out.println("hello"); }}

Object classes and transitions

When it comes to Java inheritance, you have to mention the root class of all classes: Object(java.lang.Object) class. If a class does not explicitly declare its parent class (that is, does not write extends XX), then its parent class is Object by default. Therefore, the Object class is necessary to master and understand inheritance. Java up and down transition is widely used in Java and is also built on the basis of inheritance, so Java transition is also a necessary knowledge point to master and understand inheritance.

Description of Object class

  1. Object is the root class of the class hierarchy. All classes implicitly inherit from the Object class.
  2. All Java objects have the Object default method
  3. Class Object has one constructor and is an argumentless construction

Object is the superclass of all Java classes. It is the top of the whole class inheritance structure, and is also the most abstract class. ToString (), equals(), hashCode(), wait(), notify(), getClass(), and so on are Object methods. You’ll probably run into them a lot, but more often than not, the toString() method and equals() method are the two methods that we’ll need to override to meet our needs.

The toString() method represents the string that returns the object, which needs to be overridden because each object is constructed differently, and otherwise returns the class name in the @hashCode format by default.

If we call toString() directly after overriding the toString() method, we can return our own custom output of the class as a string, rather than having to manually piece together the string output each time, greatly simplifying the output operation.

The equals() method compares two objects to see if they are equal. This is because equality doesn’t have to be the same in terms of locationThe String class, for example, overrides the euqals()* method to compare equality by the contents of the String.


Upward transformation: An automatic transformation is the instantiation of a superclass object by a subclass object (at a small scale). The logic of the upward transition is best illustrated in a single diagram:

When a parent class refers to a subclass object, it can use only the declared methods of the parent class. However, methods that are overridden execute methods of the child class, and methods that are not overridden execute methods of the parent class.

Downward transition

Downward conversion: Instantiate a subclass (small) by a parent (large) object that is written to be cast to the subclass type by parentheses (). However, the actual reference of the parent class variable must be the subclass object in order to be successfully transformed. Here, a diagram can well represent the logic of upward transformation:

When a subclass reference variable points to the object that the superclass reference variable points to (a Son() object), the downward transition is complete, and methods that are unique to the subclass but not to the superclass are invoked.

Write a case study of transition up and transition down here:

Object object=new Integer(666); Integer I =(Integer) Object; String STR =(String) String STR =(String) Object; String STR =(String) Object; // The compiler does not report an error, but the runtime does

Initialization order of child and parent classes

In Java inheritance, parent-child classes are initialized in the following order:

  1. Static member variables and static code blocks in the parent class
  2. Static member variables and static blocks of code in subclasses
  3. Ordinary member variables and code blocks in the parent class, the constructor of the parent class
  4. Common member variables and code blocks in subclasses, and constructors for subclasses

In general, static > is not static, parent class > is subclass, non-constructor > constructor. In the same category (such as ordinary variables and ordinary code blocks), member variables and code blocks are executed from front to back, requiring careful logic.

Static variables, also known as class variables, can be thought of as global variables. Static member variables and static blocks of code are initialized when the class is loaded, while non-static variables and blocks of code are initialized when the object is created. So static initialization is faster than non-static initialization.

In order to create a subclass object, we need to create a superclass object first, so the superclass takes precedence over the subclass.

When a constructor is called, it initializes the member variables, so regular member variables and code blocks take precedence over the constructor.

For a deeper understanding of why this order is in order, you need a deeper understanding of the JVM execution process. The following test code is:

Class Father{public Father() {System.out.println(++ B1 +" parent "); } static int a1=0; static int a1=0; Static {System.out.println(++ A1 +" static"); } int b1=a1; {System.out.println(++ B1 +" Parent block ");}} {System.out.println(++ B1 +" Parent block "); }} class Son extends Father{public Son() {System.out.println(++ B2 +" constructor ");}} class Son extends Father{public Son() {System.out.println(++ B2 +" constructor "); } static {System.out.println(++ A1 +" static");} static {System.out.println(++ A1 +" static"); } int b2=b1; {System.out.println(++ B2 + "subclass block ");}} {System.out.println(++ B2 +" subclass block "); } } public class test9 { public static void main(String[] args) { Son son=new Son(); }}

Execution Result:


All right, so that’s it for this time. One of the three main features of Java object-oriented is inheritance — you’ve already mastered it. Let’s take a look at the three main features of Java’s object orientation: encapsulation, inheritance, and polymorphism. Finally, can you have a general understanding of their characteristics?

Encapsulation: it is the encapsulation of the class. Encapsulation is the encapsulation of the properties and methods of the class. It only exposes the methods to the outside but does not expose the specific usage details.

Inheritance: a subclass inherits its parent, that is, “the child inherits the father’s business”. The subclass has all the private properties and methods of the parent, and it can also expand its own new properties and methods on this basis. The main purpose is to reuse code.

Polymorphism: Polymorphism is the ability to have many different manifestations or forms of the same behavior. That is, a parent class may have several subclasses, and each subclass may implement a variety of methods of the parent class. When a parent method is called, the parent class refers to variables that point to different instances of the child class and executes different methods. This is called the polymorphic parent method.

Finally, here is a picture to illustrate the relationship between them.

Click on the attention, the first time to understand Huawei cloud fresh technology ~