70000 words, a summary of basic Java knowledge

Keywords: Java data structure linked list JavaSE

catalogue

✨ Write in front

✨ Initial knowledge of Java and development environment installation

πŸ™Œ Java Language Overview

πŸŽ† What is the Java language

πŸŽ† Master Java

πŸŽ† Why Java

πŸ™Œ Is Java the best language

πŸ™Œ Installation of development environment

πŸŽ† JDK installation

πŸŽ† Installation of IEDA

✨ Data types and operators

πŸ™Œ Variables and types

  πŸŽ† Long integer variable

  πŸŽ† Double precision floating point variable

πŸŽ† Single precision floating point variable

πŸŽ† Character type variable

πŸŽ† Byte type variable

πŸŽ† Short integer variable

πŸŽ† Boolean type variable

πŸŽ† String type variable

πŸŽ† Scope of variable

  πŸŽ† Naming rules for variables

πŸŽ† constant

  πŸŽ† Understand type conversion

πŸŽ† Understanding numerical improvement

  πŸ™Œ operator

πŸŽ† Arithmetic operator

πŸŽ† Relational operator

πŸŽ† Logical operator

  πŸŽ† Bitwise Operators

  πŸŽ† Shift operation

πŸŽ† Conditional operator

πŸŽ† Operator precedence

✨ Program logic control

πŸ™Œ Sequential structure

  πŸ™Œ Branching structure

πŸŽ† if statement

  πŸŽ† switch statement

πŸ™Œ Cyclic structure

πŸŽ† while loop

πŸŽ†break

Β πŸŽ†continue

  πŸŽ† for loop

πŸ™Œ Input and output

πŸŽ† Output to console

πŸŽ† Input from keyboard

  ✨ Use of methods

πŸ™Œ Basic usage of method

πŸŽ† What is a method

πŸŽ† Method definition syntax

πŸŽ† Execution procedure of method call

πŸŽ†   Relationship between arguments and formal parameters

πŸŽ† Method with no return value

πŸ™Œ Method overload

πŸŽ† Overload problem to be solved

πŸŽ† Use overload

πŸŽ† Overloaded rules

πŸ™Œ Method recursion

πŸŽ† The concept of recursion

πŸŽ†   Recursive execution process analysis

  πŸŽ† Recursive exercise

πŸŽ† Recursive summary

✨ Definition and use of array

πŸ™Œ Basic usage of arrays

πŸŽ† What is an array

πŸŽ† Create array

πŸŽ† Use of arrays

πŸ™Œ Array as an argument to the method

πŸŽ† Basic Usage

πŸŽ† Understanding reference types

πŸŽ† Know null

πŸŽ† First knowledge of JVM memory area division

πŸŽ† Array as the return value of the method

πŸ™Œ   Two dimensional array

  ✨ Classes and objects

πŸ™Œ Preliminary cognition of class and object

  πŸ™Œ Classes and instantiation of classes

πŸŽ† class

πŸŽ† Class instantiation

  πŸ™Œ Member of class

πŸŽ† Field / attribute / member variable

πŸŽ† Method

πŸŽ† Summary

πŸ™Œ   encapsulation  

πŸŽ† private implementation encapsulation

πŸŽ† getter and setter methods

  πŸ™Œ Construction method  

πŸŽ† Basic grammar

  πŸŽ† this keyword

πŸ™Œ Recognize code blocks

πŸŽ† What is a code block

πŸŽ† Common code block

  πŸŽ† Construct code block  

  πŸŽ† Static code block

πŸ™Œ Supplementary notes

πŸŽ† toString method

πŸŽ† Anonymous object

  πŸ™Œ Summary of key contents

  ✨ object-oriented

πŸ™Œ package

πŸŽ† summary

πŸŽ† Import classes in package

πŸŽ† Static import

πŸ™Œ Putting classes in packages

πŸŽ† Basic rules

πŸŽ† Operation steps

  πŸ™Œ Access control for packages

Demo1.java

πŸŽ† Common system packages

πŸ™Œ inherit

πŸ™Œ rule of grammar

πŸŽ† Basic grammar

πŸŽ† protected keyword

  πŸŽ† More complex inheritance relationships

πŸŽ† final keyword

πŸ™Œ combination

πŸ™Œ polymorphic

πŸŽ† Upward transformation

πŸŽ† Dynamic binding

πŸŽ† Method rewrite

πŸŽ† Understanding polymorphism

πŸŽ† Downward transformation

πŸŽ† super keyword

πŸŽ† Method of calling rewriting in construction method

πŸŽ† summary

πŸ™Œ abstract class

πŸŽ† Role of abstract classes

πŸ™Œ Interface

πŸŽ† rule of grammar

πŸŽ† Implement multiple interfaces

πŸŽ† Interface usage instance

πŸŽ† summary

✨ Write in front

The basic learning of Java for more than a month has finally ended, and I have a new understanding of Java. I think this blog is very suitable for the introductory learning of Java Xiaobai. There are corresponding exercises and problem solutions at the end of each chapter, so as to consolidate my learning. The production of this blog is also very difficult for bloggers. There are many dry goods. It is recommended to collect and read it carefully. If you think this blog is good, please praise, collect and comment. Your support will be seen by more people. Don't talk more nonsense. Let's come this semester!!!

✨ Initial knowledge of Java and development environment installation

πŸ™Œ Java Language Overview

πŸŽ† What is the Java language

Java is an excellent programming language with pleasing syntax and easy to understand semantics. Moreover, Java is also a technical system formed by a series of computer software and specifications. This technical system provides a complete support environment for software development and cross platform deployment, and is widely used in embedded systems, mobile terminals, enterprise servers, large computers and other occasions.

Java developers originally wanted to register the oak trademark, but unfortunately it was used by others. So I changed my name to Java (a kind of java coffee). Java developers like to drink this kind of coffee very much, which also means offering a cup of coffee full of aroma to the world. That's why the coffee icon was born.

πŸŽ† Master Java

  James Gosling is a software expert. He was born in on May 19, 1955 Canada,Java One of the co founders of the programming language, he is generally recognized as“ Java The father of.

The title of the doctoral thesis is "the algebraic regulation of constraints". After graduation, I worked in IBM and designed the first generation of IBM workstation NeWS system, but it was not valued. Later transferred to Sun. In 1990, he cooperated with Patrick Naughton, Mike Sheridan and others in the "Green Plan", and later developed a language called "Oak", which was later renamed Java. At the end of 1994, James Gosling demonstrated Java programs at the "technology, education and Design Conference" held in Silicon Valley. In 2000, Java became the most popular computer language in the world.

πŸŽ† Why Java

  What is the relationship between JavaScript and Java? When it comes to the relationship between the two, for example. It is equivalent to the relationship between Lei Feng and Lei Fengta, or the relationship between his wife and his wife cake (there is no relationship...). At first, JavaScript was called liveScript. At that time, java was too popular, so liveScript was renamed JavaScript to promote a wave.
Β 

πŸ™Œ Is Java the best language

No, because there are more appropriate programming languages in every field.

C language is undoubtedly the king of modern computer software programming language. Almost all operating systems are written in C language. C + + is an object-oriented C language, which has been continuously improved.

Javascript is a language that can run in the browser. The rich front-end interface is inseparable from Javascript. In recent years, Node.js has occupied a place in the back end.

Python is used for system management, and provides API s for scientific computing and text processing through high-performance precompiled libraries. It is a necessary explanatory language for Linux.

So, what are the advantages of the Java language to occupy the first place in the list?

First, the syntax is relatively simple, and developers who have learned computer programming can get started quickly.

Second, it has strong competitiveness in several fields, such as server-side programming, high-performance network programs, enterprise software transaction processing, distributed computing, Android mobile terminal application development and so on.

πŸ™Œ Installation of development environment

πŸŽ† JDK installation

idea is a development tool and jdk is a development environment. There are many development tools, but the development environment can only be jdk.

For the installation of jdk, I will recommend you to station B or the installation steps written by the blogger I recommend below. Remember, you must install in the order of each step. If the installation is not good, you may be negligent.

πŸŽ† Installation of IEDA

IDEA website: https://www.jetbrains.com/idea/download/#section=windows

IDEA related videos
IDEA installation video: https://www.bilibili.com/video/BV1s44y1b7rV/
IDEA basic development settings: https://www.bilibili.com/video/BV13T4y1L7qP/
IDEA basic fast key settings: https://www.bilibili.com/video/BV1Lv411i7wD/
IDEA basic debugging method: https://www.bilibili.com/video/BV1mv411y7D5/

✨ Data types and operators

πŸ™Œ Variables and types

Variable refers to the variable quantity when the program runs   It is equivalent to opening up a memory space to save some data. Type is to divide the types of variables. Variables of different types have different characteristics

   Variables are closely related to our memory

πŸŽ† Integer variable

Basic syntax format

int Variable name = Initial value;

Code example:

public static void main(String[] args) {
        int a = 1;
        System.out.println(a);
    }

matters needing attention:

1. int indicates that the type of variable is an integer

2. The variable name is the identification of the variable. It is used later

3. In Java, = means assignment (different from Mathematics), which means setting an initial value for a variable

4. Initialization is optional, but it is recommended to explicitly initialize when creating variables

5. Finally, don't forget the semicolon, otherwise the compilation will fail

6. / / indicates comments. Comments are used as the explanation part of the code and do not participate in compilation and operation
Β 

    public static void main(String[] args) {
        //int a = 1;
        //System.out.println(a);
    }

In Java, an int variable takes up 4 bytes. It has no direct relationship with the operating system

What are bytes?

Byte is the basic unit of space size in the computer. The computer uses binary to represent data. We think that eight bits are one byte. Our usual computer is 8GB memory, which means 8G bytes. 1KB = 1024 bytes, 1MB = 1024 KB, 1GB = 1024 MB. Therefore, 8GB is equivalent to more than 8 billion bytes

The data range represented by 4 bytes is - 2 ^ 31 - > 2 ^ 31-1, which is about - 2.1 billion to + 2.1 billion
Β 

Β 

  Use the following code to view the integer data range in Java:

 public static void main(String[] args) {
        System.out.println(Integer.MAX_VALUE);  // Maximum value of int
        System.out.println(Integer.MIN_VALUE);  // Minimum value of int
    }

  If the result of the operation exceeds the maximum range of int, overflow will occur

 public static void main(String[] args) {
        int maxValue = Integer.MAX_VALUE;
        System.out.println(maxValue+1);
        int minValue = Integer.MIN_VALUE;
        System.out.println(minValue-1);
    }

  πŸŽ† Long integer variable

Basic syntax format:

long Variable name = Initial value;

Code example:

 public static void main(String[] args) {
        long num = 10L; // Define a long integer variable, and the initial value can be written as 10l (lowercase L, not number 1)
        System.out.println(num) ;
 
    }

matters needing attention:

1. The basic syntax format is basically the same as that of creating int variables, except that the type is changed to long

2. The initialization setting value is 10l, which represents a long integer number. 10l is also OK

3. 10 can also be used for initialization. The type of 10 is int, and the type of 10L is long. It is better to use 10 L or 10 L

In Java, the long type takes up 8 bytes. The data range represented is - 2 ^ 63 - > 2 ^ 63-1

Use the following code to view the long data range in Java:

  public static void main(String[] args) {
        System.out.println(Long.MAX_VALUE);
        System.out.println(Long.MIN_VALUE);
    }

  πŸŽ† Double precision floating point variable

Basic syntax format

double Variable name = Initial value;

Code example:

  public static void main(String[] args) {
        double num = 1.0;
        System.out.println(num);
    }

 public static void main(String[] args) {
        int a = 1;
        int b = 2;
        System.out.println(a / b);
    }

In Java, the value of int divided by int is still int (the decimal part will be discarded directly)

If you want to get 0.5, you need to use double type calculation

  public static void main(String[] args) {
        double a = 1.0;
        double b = 2.0;
        System.out.println(a / b);
    }

 public static void main(String[] args) {
            double num = 1.1;
            System.out.println(num * num);
        }

  Although the double in Java is also 8 bytes, the memory layout of floating-point numbers is very different from that of integers, and the data range cannot be simply expressed in the form of 2 ^ n. the memory layout of Java's double type complies with IEEE 754 standard (the same as C language). If you try to use limited memory space to represent possibly infinite decimal points, there will be some precision error

πŸŽ† Single precision floating point variable

Basic format:

float Variable name = Initial value;

Code example:

  public static void main(String[] args) {
            float num = 1.0f;    // Writing 1.0F is also OK
            System.out.println(num);
        }

  float   Type occupies four bytes in Java and also complies with IEEE 754 standard. Due to the small range of data accuracy, double is preferred when floating-point numbers are used in engineering, and float is not recommended.

πŸŽ† Character type variable

Basic format:

char Variable name = Initial value;

  Code example:

   public static void main(String[] args) {
            char ch = 'A';
            System.out.println(ch);
        }

matters needing attention:

1. In Java, the form of single quotation mark + single letter is used to represent the character literal value

2. The character in the computer is essentially an integer. ASCII is used to represent the character in C language, while Unicode is used to represent the character in Java. Therefore, a character occupies two bytes and represents more types of characters, including Chinese

   public static void main(String[] args) {
            char ch = 'Oh';
            System.out.println(ch);
        }

πŸŽ† Byte type variable

Basic syntax format:

byte Variable name = Initial value; 

Code example:

  public static void main(String[] args) {
            byte value = 0;
            System.out.println(value);
        }

matters needing attention:

1. The byte type also represents an integer. It only occupies one byte and represents a small range (- 128 - > + 127)

2. Byte type and character type are irrelevant

πŸŽ† Short integer variable

Basic syntax format:

short Variable name = Initial value; 

  Code example:

 public static void main(String[] args) {
            short value = 0;
            System.out.println(value);
        }

matters needing attention:

1. short takes up 2 bytes and represents the data range of - 32768 - > + 32767

2. The scope of this expression is relatively small, and it is generally not recommended

πŸŽ† Boolean type variable

Basic syntax format:

boolean Variable name = Initial value;

Code example:

 public static void main(String[] args) {
            boolean value = true;
            System.out.println(value);
        }

matters needing attention:  

1. There are only two values for Boolean variables. True means true and false means false

2. Java boolean type and int cannot be converted to each other. There is no such usage as 1 for true and 0 for false

3. boolean type. Some JVM s occupy 1 byte and some occupy 1 bit.
Β 

  Test.java:4: error: wrong operand type of binary operator '+', System.out.println(value + 1);

πŸŽ† String type variable

Basic syntax format:

String Variable name = "Initial value"; 

Code example:

  public static void main(String[] args) {
            String name = "zhangsan";
            System.out.println(name);
        }

matters needing attention:

1. Java uses double quotation marks + several characters to represent string literals

2. Different from the above types, String is not a basic type, but a reference type (explained later)

3. Some specific characters in the string that are not convenient for direct representation need to be escaped

The + operation of string indicates string splicing:

public static void main(String[] args) {
            String a = "hello";
            String b = "world";
            String c = a + b;
            System.out.println(c);
        }

  You can also splice strings and integers:

  public static void main(String[] args) {
            String str = "result = ";
            int a = 10;
            int b = 20;
            String result = str + a + b;
            System.out.println(result);
        }

Therefore, we can easily use System.out.println to print multiple strings or numbers at the same time

    public static void main(String[] args) {
            int a = 10;
            int b = 20;
            System.out.println("a = " + a + ",b = " + b);
        }

πŸŽ† Scope of variable

That is, the range within which the variable can take effect, which is generally the code block where the variable definition is located

  πŸŽ† Naming rules for variables

Hard index:

1. A variable name can only contain numbers, letters and underscores

2. The number cannot begin

3. Variable names are case sensitive. That is, Num and num are two different variables

Soft index:

1. Variable naming shall be descriptive, see the meaning of name

2. The variable name should not use pinyin (but not absolute)

3. Nouns are recommended for the part of speech of variable names

4. The small hump naming method is recommended for variable naming. When a variable name is composed of multiple words, the initials of other words are capitalized except the first word

Example of small hump naming:

int maxValue = 100; 
String studentName = "Zhang San";

πŸŽ† constant

literal constant

10 // int literal constant (decimal) 
010 // The int literal constant (octal) starts with the number 0. 010 is the decimal 8 
0x10 // The int literal constant (hexadecimal) starts with the number 0x. 0x10 is the decimal 16 
10L // long literal constant. It can also be written as 10l (lowercase L) 
1.0 // double literal constant. It can also be written as 1.0D or 1.0D 
1.5e2 // double literal constant. Expressed in scientific notation. Equivalent to 1.5 * 10 ^ 2 
1.0f // float literal constant can also be written as 1.0F 
true // boolen literal constant, and also false 
'a' // char literal constant. There can only be one character in single quotation marks
"abc" // String literal constant. There can be multiple characters in double quotation marks

Constant modified by final keyword

  πŸŽ† Understand type conversion

Long indicates a larger range. You can assign int to long, but you can't assign long to int

Double represents a larger range. You can assign int to double, but you can't assign double to int

Conclusion: the assignment between variables of different numerical types indicates that the type with smaller range can be implicitly converted to the type with larger range, otherwise it will not

int and boolean are assigned to each other

Conclusion: int and boolean are two irrelevant types and cannot be assigned to each other

The int literal constant assigns a value to byte

Note: the data range represented by byte is - 128 - > + 127, 256 has exceeded the range, and 100 is still within the range

Conclusion: when using literal constant assignment, Java will automatically perform some checks to determine whether the assignment is reasonable

Use cast

  public static void main(String[] args) {
            int a = 0;
            double b = 10.5;
            a = (int)b;
            System.out.println(a);
        }

Β 

Conclusion: double type can be forcibly converted to int

1. Mandatory type conversion may cause precision loss. As in the example just now, after assignment, 10.5 becomes 10, and the part after the decimal point is ignored

2. Forced type conversion is not always successful, and irrelevant types cannot be forced

Type conversion summary

1. Assignment between variables of different numeric types indicates that types with a smaller range can be implicitly converted to types with a larger range

2. If you need to assign a type with a large range to a type with a small range, you need to force type conversion, but the precision may be lost

3. When assigning a literal constant, Java will automatically check the number range

πŸŽ† Understanding numerical improvement

Mixed operation of int and long

public static void main(String[] args) {
            int a = 10;
            long b = 20;
            int c = a + b; // Compilation error, prompt that converting long to int will lose precision
            long d = a + b; // Compile passed
        }

Conclusion:

When int and long are mixed, int will be promoted to long, and the result will still be of long type. You need to use variables of long type to receive the result

If you have to use int to receive results, you need to use cast

Operation of byte and byte

   public static void main(String[] args) {
            byte a = 10;
            byte b = 20;
            byte c = a + b;
            System.out.println(c);
 
            // Compilation error Test.java:5: error: incompatible type: conversion from int to byte may be lost
        }

Conclusion:

Byte and byte are of the same type, but there is a compilation error. The reason is that although a and b are both bytes, calculating a + b will first promote a and b to int, and then calculate. The result is also int. if this is assigned to c, the above error will occur

Correct writing:

public static void main(String[] args) {
            byte a = 10;
            byte b = 20;
            byte c = (byte)(a + b);
            System.out.println(c);
        }

Summary of type promotion:

1. For mixed operations of different types of data, those with a small range will be promoted to those with a large range

2. For short and byte types smaller than 4 bytes, they will be promoted to 4-byte int before operation

Conversion between int and String

Convert int to String

    public static void main(String[] args) {
            int num = 10;
            // Method 1
            String str1 = num + "";
            // Method 2
            String str2 = String.valueOf(num);
            System.out.println(str1);
            System.out.println(str2);
        }

Convert String to int

   public static void main(String[] args) {
            String str = "100";
            int num = Integer.parseInt(str);
            System.out.println(str);
        }

  πŸ™Œ operator

πŸŽ† Arithmetic operator

Basic four operators

 + - * / %

a) The result of int / int or int needs to be calculated with double

 public static void main(String[] args) {
        int a = 1;
        int b = 2;
        System.out.println(a / b);
    }

  b)0 cannot be a divisor

   public static void main(String[] args) {
        int a = 1;
        int b = 0;
        System.out.println(a / b);
    }  

  c) % means remainder. You can find modules not only for int, but also for double

System.out.println(11.5 % 2.0);

Incremental assignment operator + = - = * = / =%=

public static void main(String[] args) {
        int a = 10;
        a += 1; // Equivalent to a = a + 1
        System.out.println(a);
    }

  Auto increment / Auto decrement operator + +--

  public static void main(String[] args) {
        int a = 10;
        int b = ++a;
        System.out.println(b);
        int c = a++;
        System.out.println(c);
    }

Conclusion:

1. If the return value of the expression is not taken from the increment operation, there is no difference between pre increment and post increment

2. If the return value of the expression is taken, the return value of pre auto increment is the value after auto increment, and the return value of post auto increment is the value before auto increment

πŸŽ† Relational operator

== != < > =
public static void main(String[] args) {
        int a = 10;
        int b = 20;
        System.out.println(a == b);
        System.out.println(a != b);
        System.out.println(a < b);
        System.out.println(a > b);
        System.out.println(a <= b);
        System.out.println(a >= b);
    }

Note: the expression return values of relational operators are boolean

πŸŽ† Logical operator

&& || !

Note: the operands (operands are often the result of relational operators) and return values of logical operators are boolean

Logic and&&

Rule: if both operands are true, the result is true, otherwise the result is false

 public static void main(String[] args) {
        int a = 10;
        int b = 20;
        int c = 30;
        System.out.println(a < b && b < c);
    }

Logical or||

Rule: if both operands are false, the result is false, otherwise the result is true

 public static void main(String[] args) {
        int a = 10;
        int b = 20;
        int c = 30;
        System.out.println(a < b || b < c);
    }

Logical non!

Rule: the operand is true and the result is false; The operand is false and the result is true (this is a unary operator with only one operand)

  public static void main(String[] args) {
        int a = 10;
        int b = 20;
        System.out.println(!(a < b));
    }

  Short-circuit evaluation

&&And | observe the rules of short circuit evaluation

1. For & &, if the left expression value is   False, the overall value of the expression must be false, and there is no need to evaluate the expression on the right

2. For πž“œ, if the left expression value is true, the overall value of the expression must be true, and there is no need to calculate the right expression

  public static void main(String[] args) {
        //We all know that calculating 10 / 0 will cause the program to throw an exception 
        //But the code works normally, indicating that 10 / 0 is not really evaluated
        System.out.println(10 > 20 && 10 / 0 == 0); // Print false
        System.out.println(10 < 20 || 10 / 0 == 0); // Print true
    }

  πŸŽ† Bitwise Operators

& | ~ ^

  Bitwise AND &: if both binary bits are 1, the result is 1, otherwise the result is 0

 public static void main(String[] args) {
        int a = 10;
        int b = 20;
        System.out.println(a & b);
    }

  Bitwise or |: if both binary bits are 0, the result is 0, otherwise the result is 1

   public static void main(String[] args) {
        int a = 10;
        int b = 20;
        System.out.println(a|b);
    }

  be careful:   When the operands of & and | are integers (int, short, long, byte), they represent bitwise operation; when the operands are boolean, they represent logical operation

Reverse by bit ~: if this bit is 0, it turns to 1; if this bit is 1, it turns to 0

  public static void main(String[] args) {
        int a = 0xf;
        System.out.printf("%x\n", ~a);
 
    }

be careful:

1. The number of 0x prefix is hexadecimal number. Hexadecimal can be regarded as a simplified representation of binary. A hexadecimal number corresponds to 4 binary bits

2. 0xf represents 15 in hexadecimal, that is, 1111 in binary

3. printf can format the output content,% x means output in hexadecimal

4. \n indicates a newline character

Bitwise exclusive or ^: if the binary bits of two numbers are the same, the result is 0, and if they are different, the result is 1

 public static void main(String[] args) {
        int a = 0x1;
        int b = 0x2;
        System.out.printf("%x\n", a ^ b);
    }

  πŸŽ† Shift operation

<< >> 

  Move left < <: don't use the leftmost position, and fill 0 on the rightmost position

 public static void main(String[] args) {
        int a = 0x10;
        System.out.printf("%x\n", a << 1);
    }

  Shift right > >: do not use the rightmost bit, and fill the symbol bit on the left   (positive numbers complement 0, negative numbers complement 1)

  public static void main(String[] args) {
        int a = 0x10;
        System.out.printf("%x\n", a >> 1);
        // Run results (note that they are printed in hexadecimal)
        //8
        int b = 0xffff0000;
        System.out.printf("%x\n", b >> 1);
        // Run results (note that they are printed in hexadecimal)
        //ffff8000
    }

πŸŽ† Conditional operator

Expression 1 ? Expression 2 : Expression 3

When the value of expression 1 is true, the value of the whole expression is the value of expression 2; When the value of expression 1 is false, the value of the entire expression is the value of expression 3

 public static void main(String[] args) {
        // Find the maximum of two integers
        int a = 10;
        int b = 20;
        int max = a > b ? a : b;
        System.out.println(max);
    }

πŸŽ† Operator precedence

public static void main(String[] args) {
        System.out.println(1 + 2 * 3);
    }

 public static void main(String[] args) {
        System.out.println(10 < 20 && 20 < 30);
 
    }

  At this time, it is obvious to calculate 10 < 20 and 20 < 30 first, and then calculate & &. Otherwise, the operation of 20 & & 20 is syntactically incorrect (& & operands can only be boolean)

Summary

1.% operation can also be calculated for double in Java

2. It is necessary to distinguish between pre auto increment and post auto increment

3. Because Java is a strongly typed language, the type check is strict, so the operands such as & & must be boolean

4. Distinguish clearly when & and | represent bitwise operation and when they represent logical operation

✨ Program logic control

πŸ™Œ Sequential structure

The sequential structure is relatively simple. For example, the code we wrote before is a sequential structure, which is executed line by line in the order in which the code is written.

public static void main(String[] args) {
        System.out.println("aaa");
        System.out.println("bbb");
        System.out.println("ccc");
    }

  If you adjust the writing order of the code, the execution order also changes

 public static void main(String[] args) {
        System.out.println("aaa");
        System.out.println("ccc");
        System.out.println("bbb");
    }

  πŸ™Œ Branching structure

πŸŽ† if statement

Basic grammatical form 1

if(Boolean expression){
    //Execute code when conditions are met
}

Basic grammatical form 2

if(Boolean expression){
    //Execute code when conditions are met
}else{
    //Execute code when conditions are not met
}

Basic grammatical form 3  

if(Boolean expression){
    //Execute code when conditions are met
}else if(Boolean expression){
    //Execute code when conditions are met
}else{
    //Execute code when none of the conditions are met
}

Code example 1:   Determine whether a number is odd or even

public static void main(String[] args) {
        int num = 10;
        if (num % 2 == 0) {
            System.out.println("num It's an even number");
        } else {
            System.out.println("num It's an odd number");
        }
    }

Code example 2:   Determine whether a number is positive or negative

 public static void main(String[] args) {
        int num = 10;
        if (num > 0) {
            System.out.println("num Is a positive number");
        } else if (num < 0) {
            System.out.println("num Is a negative number");
        } else {
            System.out.println("num Is 0");
        }
    }
 

Code example 3:   Determine whether a year is a leap year

 public static void main(String[] args) {
        int year = 2000;
        if (year % 100 == 0) {
            // Judgment century leap year
            if (year % 400 == 0) {
                System.out.println("It's a leap year");
            } else {
                System.out.println("Not a leap year");
            }
        } else {
            // Ordinary leap year
            if (year % 4 == 0) {
                System.out.println("It's a leap year");
            } else {
                System.out.println("Not a leap year");
            }
        }
}

  Drape else problem

   public static void main(String[] args) {
        int x = 10;
        int y = 10;
        if (x == 10)
            if (y == 10)
                System.out.println("aaa");
            else
                System.out.println("bbb");
    }
//When writing code, try to put parentheses in if and else

  πŸŽ† switch statement

Basic grammar

switch(integer|enumeration|character|character string){
 case Content 1 : {
 Execute statement when content is satisfied;
 [break;]
 }
 case Content 2 : {
 Execute statement when content is satisfied;
 [break;]
 }
 ...
 default:{
 Execute the statement when the content is not satisfied;
 [break;]
 } 
}

Code example:   Output the week according to the value of day

  public static void main(String[] args) {
        int day = 1;
        switch(day) {
            case 1:
                System.out.println("Monday");
                break;
            case 2:
                System.out.println("Tuesday");
                break;
            case 3:
                System.out.println("Wednesday");
                break;
            case 4:
                System.out.println("Thursday");
                break;
            case 5:
                System.out.println("Friday");
                break;
            case 6:
                System.out.println("Saturday");
                break;
            case 7:
                System.out.println("Sunday");
                break;
            default:
                System.out.println("Incorrect input");
                break;
        }
    }

According to the different values of the switch, the corresponding case statement will be executed. The case statement will be ended when a break is encountered. If the value in the switch does not match the case, the statement in default will be executed. We suggest that a switch statement should preferably carry default.

Note 1 do not omit break, otherwise the effect of "multi branch selection" will be lost

public static void main(String[] args) {
        int day = 1;
        switch(day) {
            case 1:
                System.out.println("Monday");
                // break;
            case 2:
                System.out.println("Tuesday");
                break;
        }
 
    }

  Note 2 the value in switch can only be integer | enumeration | character | string

   public static void main(String[] args) {
        double num = 1.0;
        switch(num) {
            case 1.0:
                System.out.println("hehe");
                break;
            case 2.0:
                System.out.println("haha");
                break;
        }
    }

Note 3 switch cannot express complex conditions

/ for example: If num The value of is between 10 and 20, Just print hehe
// Such code is easy to express using if, but it cannot be expressed using switch 
if (num > 10 && num < 20) {
 System.out.println("hehe");
}

πŸ™Œ Cyclic structure


πŸŽ† while loop

Basic syntax format:

while(Cycle condition){ 
Circular statement; 
}

Code example 1:   Print numbers 1 - 10

 public static void main(String[] args) {
        int num = 1;
        while (num <= 10) {
            System.out.print(" "+num);
            num++;
        }
    }

Code example 2:   Calculate the sum of 1 - 100

  public static void main(String[] args) {
        int n = 1;
        int result = 0;
        while (n <= 100) {
            result += n;
            n++;
        }
        System.out.println(result);
    }

Code example 3:   Calculate the factorial of 5

  public static void main(String[] args) {
        int n = 1;
        int result = 1;
        while (n <= 5) {
            result *= n;
            n++;
        }
        System.out.println(result);
    }

Code example 4:   Calculate 1+ 2! + 3! + 4! + 5!

public static void main(String[] args) {
        int num = 1;
        int sum = 0;
       // The outer loop is responsible for finding the sum of factorials
        while (num <= 5) {
            int factorResult = 1;
            int tmp = 1;
            // The inner loop is responsible for the details of factoring
            while (tmp <= num) {
                factorResult *= tmp;
                tmp++;
            }
            sum += factorResult;
            num++;
        }
        System.out.println("sum = " + sum);
    }

matters needing attention

1. Similar to if, the statement under while may not write {}, but only one statement can be supported when it is not written. It is recommended to add {}

2. Similar to if, the {suggestion after while is written on the same line as while

3. Similar to if, do not write more semicolons after while, otherwise the loop may not execute correctly
Β 

int num = 1; 
while (num <= 10); { 
 System.out.println(num); 
 num++; 
} 
// results of enforcement
[No output, Program dead loop]

πŸŽ†break

The function of break is to end the loop early.

Code example:   Find the multiple of the first 3 in 100 - 200

 public static void main(String[] args) {
        int num = 100;
        while (num <= 200) {
            if (num % 3 == 0) {
                System.out.println("A multiple of 3 was found, by:" + num);
                break;
            }
            num++;
        }
    }

Β πŸŽ†continue

The function of continue is to skip this cycle and immediately enter the next cycle

Code example:   Find multiples of all 3 in 100 - 200

  public static void main(String[] args) {
        int num = 100;
        while (num <= 200) {
            if (num % 3 != 0) {
                num++; // Don't forget the + + here! Otherwise it will loop
                continue;
            }
            System.out.println("A multiple of 3 was found, by:" + num);
            num++;
        }
    }

  πŸŽ† for loop

Basic grammar

for(Expression 1;Expression 2;Expression 3){ 
Circulatory body; 
} 

Expression 1: used to initialize a loop variable

Expression 2: loop condition

Expression 3: update loop variable

Code example 1:   Print numbers 1 - 10

for (int i = 1; i <= 10; i++) { 
 System.out.println(i); 
} 

Code example 2:   Calculate the sum of 1 - 100

int sum = 0; 
for (int i = 1; i <= 100; i++) { 
 sum += i; 
} 
System.out.println("sum = " + sum); 
// results of enforcement
5050 

Code example 3:   Calculate the factorial of 5

int result = 0; 
for (int i = 1; i <= 5; i++) { 
 result *= i; 
} 
System.out.println("result = " + result); 

Precautions (similar to while loop)

1. Similar to if, the statement below for may not write {}, but only one statement can be supported when it is not written. It is recommended to add {}

2. Similar to if, the {suggestion after for is written on the same line as while

3. Similar to if, do not write more semicolons after for, otherwise the loop may not execute correctly
Β 

πŸ™Œ Input and output

πŸŽ† Output to console

Basic grammar

  public static void main(String[] args) {
        System.out.println("msg"); // Output a string with newline
        System.out.print("msg"); // Output a string without line breaks
        System.out.printf("format, msg"); // Format output
    }

println output comes with \ n,

The format output mode of print without printf is basically the same as that of printf in C language

format string

πŸŽ† Input from keyboard

Use Scanner to read string / integer / floating point number

import java.util.Scanner; // The util package needs to be imported
public class fsfa {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("Please enter your name:");
        String name = sc.nextLine();
        System.out.println("Please enter your age:");
        int age = sc.nextInt();
        System.out.println("Please enter your salary:");
        float salary = sc.nextFloat();
        System.out.println("Your information is as follows:");
        System.out.println("full name: "+name+"\n"+"Age:"+age+"\n"+"Salary:"+salary);
        sc.close(); // Note that remember to call the close method
    }
}

  Use the Scanner loop to read N numbers

import java.util.Scanner; // The util package needs to be imported
public class fsfa {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        double sum = 0.0;
        int num = 0;
        while (sc.hasNextDouble()) {
            double tmp = sc.nextDouble();
            sum += tmp;
            num++;
        }
        System.out.println("sum = " + sum);
        System.out.println("avg = " + sum / num);
        sc.close();
    }
}

  ✨ Use of methods

πŸ™Œ Basic usage of method

πŸŽ† What is a method

Significance of method existence (don't recite, focus on experience):

1. It is a modular organization code (when the code scale is complex)

2. Make sure that the code is reused, and one code can be used in multiple locations

3. Make the code easier to understand

4. Directly call the existing method for development, and there is no need to make wheels repeatedly

Recall a previously written code: calculate 1! + 2! + 3! + 4! + 5!

int sum = 0;
for (int i = 1; i <= 5; i++) {
    int tmp = 1;
    for (int j = 1; j <= i; j++) {
        tmp *= j;
   }
    sum += tmp;
}
System.out.println("sum = " + sum);

πŸŽ† Method definition syntax

Basic grammar

// Method definition
public static Method return value method name([Parameter type parameter ...]){
 Method body code;
 [return Return value];
}
// Method call
 Return value variable = Method name(Argument...);

Code example: implement a method to add two integers

        public static void main(String[] args) {
            int a = 10;
            int b = 20;
 
            // Method call
            int ret = add(a, b);
            System.out.println("ret = " + ret);
        }
        // Definition of method
        public static int add(int x, int y) {
            return x + y;
        }

matters needing attention

1. public and static keywords have specific meanings here. We won't discuss them for the time being, and we'll introduce them in detail later

2. When defining a method, there can be no parameters. Each parameter must specify a type

3. When defining a method, the return value can also be null. If there is no return value, the return value type should be written as void

4. Parameters during method definition are called "formal parameters", and parameters during method call are called "arguments"

5. The method definition must be in the class, and the code can be written above or below the calling position

6. There is no concept of "function declaration" in Java

πŸŽ† Execution procedure of method call

Basic rules

When defining a method, the code of the method will not be executed. It will only be executed when calling

When the method is called, the argument is assigned to the formal parameter

After the parameter is passed, it will be executed to the method body code

After the method is executed (when a return statement is encountered), it is executed. Return to the method call location and continue to execute

A method can be called multiple times

Code example 1 calculates the addition of two integers

public static void main(String[] args) {
        int a = 10;
        int b = 20;
        System.out.println("Before the method is called for the first time");
        int ret = add(a, b);
        System.out.println("After the first method call");
        System.out.println("ret = " + ret);
        System.out.println("Before the second method call");
        ret = add(30, 50);
        System.out.println("After the second method call");
        System.out.println("ret = " + ret);
    }
    public static int add(int x, int y) {
        System.out.println("In calling method x = " + x + " y = " + y);
        return x + y;
    }

Code example: calculate 1+ 2! + 3! + 4! + 5!

public static void main(String[] args) {
        int sum = 0;
        for (int i = 1; i <= 5; i++) {
            sum += factor(i);
        }
        System.out.println("sum = " + sum);
    }
    public static int factor(int n) {
        System.out.println("calculation n Factorial of! n = " + n);
        int result = 1;
        for (int i = 1; i <= n; i++) {
            result *= i;
        }
        return result;
    }

N! Drawing explanation as an example

public static int fac(int n){
        if(n==1){
            return 1;
        }
        int tmp = n * fac(n-1);
        return tmp;
    }
 
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int y = fac(n);
        System.out.println(y);
    }

πŸŽ†   Relationship between arguments and formal parameters

Code example: exchanging two integer variables

public static void main(String[] args) {
        int a = 10;
        int b = 20;
        swap(a, b);
        System.out.println("a = " + a + " b = " + b);
    }
    public static void swap(int x, int y) {
        int tmp = x;
        x = y;
        y = tmp;
    }

  Cause analysis

The code just now did not complete the data exchange

For the basic type, the formal parameter is equivalent to a copy of the argument, that is, a value passing call

int a = 10;
int b = 20;
int x = a;
int y = b;
int tmp = x;
x = y;
y = tmp;

As you can see, the modifications to x and y do not affect a and b

Solution: pass reference type parameters (such as array to solve this problem)

public static void main(String[] args) {
        int[] arr = {10, 20};
        swap(arr);
        System.out.println("a = " + arr[0] + " b = " + arr[1]);
    }
    public static void swap(int[] arr) {
        int tmp = arr[0];
        arr[0] = arr[1];
        arr[1] = tmp;
    }

πŸŽ† Method with no return value

The return value of the method is optional. Sometimes it can not be

Code example

 public static void main(String[] args) {
        int a = 10;
        int b = 20;
        print(a, b);
    }
    public static void print(int x, int y) {
        System.out.println("x = " + x + " y = " + y);
    }

πŸ™Œ Method overload

πŸŽ† Overload problem to be solved

Code example

class Test {
 public static void main(String[] args) {
 int a = 10;
 int b = 20;
 int ret = add(a, b);
 System.out.println("ret = " + ret);
 double a2 = 10.5;
 double b2 = 20.5;
 double ret2 = add(a2, b2);
 System.out.println("ret2 = " + ret2);
 }
 public static int add(int x, int y) {
 return x + y;
 }
}
// Compilation error
//Test.java:13: error: incompatible type: conversion from double to int may be lost
//              double ret2 = add(a2, b2);

So should you create such code?

class Test {
 public static void main(String[] args) {
 int a = 10;
 int b = 20;
 int ret = addInt(a, b);
 System.out.println("ret = " + ret);
 double a2 = 10.5;
 double b2 = 20.5;
 double ret2 = addDouble(a2, b2);
 System.out.println("ret2 = " + ret2);
 }
 public static int addInt(int x, int y) {
 return x + y;
 }
 public static double addDouble(double x, double y) {
 return x + y;
 }
}

This is correct (for example, Go language does this), but Java thinks that the name addInt is unfriendly, so it's better to call it add directly.

πŸŽ† Use overload

Code example

public static void main(String[] args) {
        int a = 10;
        int b = 20;
        int ret = add(a, b);
        System.out.println("ret = " + ret);
        double a2 = 10.5;
        double b2 = 20.5;
        double ret2 = add(a2, b2);
        System.out.println("ret2 = " + ret2);
        double a3 = 10.5;
        double b3 = 10.5;
        double c3 = 20.5;
        double ret3 = add(a3, b3, c3);
        System.out.println("ret3 = " + ret3);
    }
       public static int add(int x, int y) {
        return x + y;
    }
       public static double add(double x, double y) {
        return x + y;
    }
       public static double add(double x, double y, double z) {
        return x + y + z;
    }

  The names of the methods are all add. But some add is to calculate the addition of int, and some are double addition; Some calculate the addition of two numbers, and some calculate the addition of three numbers. The same method name provides different versions of implementations, called   Method overload.

πŸŽ† Overloaded rules

For the same class, it can also be different classes:

Same method name

Method has different parameters (number of parameters or parameter type)

The return value type of the method does not affect overloading

Code example

class Test {
 public static void main(String[] args) {
 int a = 10;
 int b = 20;
 int ret = add(a, b);
 System.out.println("ret = " + ret);
 }
 public static int add(int x, int y) {
 return x + y;
 }
 public static double add(int x, int y) {
 return x + y;
 }
}
// Compilation error
//Test.java:13: error: method add(int,int) has been defined in class test

πŸ™Œ Method recursion

πŸŽ† The concept of recursion

When a method calls itself in the process of execution, it is called "recursion". Recursion is equivalent to mathematical induction. It has a starting condition and then a recurrence formula.

For example, we ask n! Starting condition: when N = 1, n! 1. This starting condition is equivalent to the end condition of recursion. Recursion formula: find n, It's hard to find directly. You can convert the problem into n! = > N * (N-1)!

Code example: recursively find the factorial of N

public static int fac(int n){
        if(n==1){
            return 1;
        }
        int tmp = n * fac(n-1);
        return tmp;
    }
 
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int y = fac(n);
        System.out.println(y);
    }

πŸŽ†   Recursive execution process analysis

  public static void main(String[] args) {
        int n = 5;
        int ret = factor(n);
        System.out.println("ret = " + ret);
    }
    public static int factor(int n) {
        System.out.println("Function start, n = " + n);
        if (n == 1) {
            System.out.println("End of function, n = 1 ret = 1");
            return 1;
        }
        int ret = n * factor(n - 1);
        System.out.println("End of function, n = " + n + " ret = " + ret);
        return ret;
    }

  πŸŽ† Recursive exercise

Code example 1 prints each bit of a number in sequence (for example, 1234 prints 1 2 3 4)

public static void print(int num) {
    if (num > 9) {
        print(num / 10);
   }
    System.out.println(num % 10);
}

Code example 2 recursively find 1 + 2 + 3 +... + 10

public static int sum(int num) { 
 if (num == 1) { 
 return 1; 
 } 
 return num + sum(num - 1); 
} 

Code example 3 writes a recursive method, enters a non negative integer and returns the sum of the numbers that make up it. For example, if you enter 1729, you should return 1 + 7 + 2 + 9, and its sum is 19

public static int sum(int num) { 
 if (num < 10) { 
 return num; 
 } 
 return num % 10 + sum(num / 10); 
} 

Code example 4 find the nth item of Fibonacci sequence

public static int fib(int n) { 
 if (n == 1 || n == 2) { 
 return 1; 
 } 
 return fib(n - 1) + fib(n - 2); 
} 
 //Loop (iterative) implementation
    public static int fib2(int n) {
        if(n == 1 || n == 2) {
            return 1;
        }
        int f1 = 1;
        int f2 = 1;
        int f3 = 0;
        for (int i = 3; i <= n; i++) {
            f3 = f1+f2;
            f1 = f2;
            f2 = f3;
        }
        return f3;
    } 

πŸŽ† Recursive summary

Recursion is an important way to solve programming problems

Some problems are naturally defined recursively (such as Fibonacci sequence, binary tree, etc.), so it is easy to use recursive solutions

Some problems can be solved by using recursion and non recursion (loop). It is more recommended to use loop at this time. Compared with recursion, non recursive programs are more efficient

✨ Definition and use of array

πŸ™Œ Basic usage of arrays

πŸŽ† What is an array

Arrays essentially allow us to "batch" create variables of the same type

For example:

If you need to represent two data, you can directly create two variables int a; int b

If you need to represent five data, you can create five variables int a1; int a2; int a3; int a4; int a5;

However, if you need to represent 10000 data, you can't create 10000 variables. At this time, you need to use arrays to help us create them in batch

matters needing attention:   In Java, the variables contained in the array must be of the same type

πŸŽ† Create array

Basic grammar

// dynamic initialization
 data type[] Array name = new data type [] { Initialization data };
// initiate static
 data type[] Array name = { Initialization data };
int[] arr = new int[]{1, 2, 3};
int[] arr = {1, 2, 3};

  matters needing attention:   During static initialization, the number of array elements is consistent with the format of initialization data

πŸŽ† Use of arrays

Code ex amp le: get length & access element

 public static void main3(String[] args) {
        int[] array = {1,2,3,4,5,6};
        //System.out.println(array.length);
        System.out.println(array[3]);
        array[3] = 19;
        System.out.println(array[3]);
    }

 int[] arr = {1, 2, 3};
        // Get array length
        System.out.println("length: " + arr.length); // Implementation result: 3
        // Accessing elements in an array
        System.out.println(arr[1]); // Execution result: 2
        System.out.println(arr[0]); // Execution result: 1
        arr[2] = 100;
        System.out.println(arr[2]); // Execution result: 100

matters needing attention

1. Use arr.length to obtain the length of the array. This operation is a member access operator. It will be often used in object-oriented later

2. Press [] to mark the array elements. Note that the subscript counts from 0

3. Use [] to read and modify data

4. The subscript access operation cannot exceed the valid range [0, length - 1]. If it exceeds the valid range, the subscript out of range exception will occur
Β 

Code example: subscript out of bounds

public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        System.out.println(arr[100]);
 
    }

Code example: traversal array

 public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }

  Code example: use for each to traverse an array

public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        for (int x : arr) {
            System.out.println(x);
        }
 
    }

πŸ™Œ Array as an argument to the method

πŸŽ† Basic Usage

Code example: print array contents

public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        printArray(arr);
    }
    public static void printArray(int[] a) {
        for (int x : a) {
            System.out.println(x);
        }
    }

πŸŽ† Understanding reference types

Code example 1   Parameter passed to array type

  public static void printf(int[] array) {
        for (int i = 0; i < array.length; i++) {
            System.out.print(array[i]+" ");
        }
        System.out.println();
    }
    public static void main(String[] args) {
        int[] array = {1,2,3,4,5,6};
        printf(array);
    }

Β 

  Code example 2   Parameter passed to built-in type

public static void func1(int[] array) {
        array = new int[]{11,2,13,4,51,61};
    }
    public static void func(int[] array) {
        array[0] = 899;
    }
    public static void main(String[] args) {
        int[] array = {1,2,3,4,5,6};
        System.out.println(Arrays.toString(array));
        func1(array);
        System.out.println(Arrays.toString(array));
    }

public static void func1(int[] array) {
        array = new int[]{11,2,13,4,51,61};
    }
    public static void func2(int[] array) {
        array[0] = 899;
    }
    public static void main(String[] args) {
        int[] array = {1,2,3,4,5,6};
        System.out.println(Arrays.toString(array));
        func2(array);
        System.out.println(Arrays.toString(array));
    }

Β 

Β 

  Summary:   In essence, the so-called "reference" only stores an address. Java sets the array as a reference type. In this way, the subsequent array parameter transfer is actually just to pass the address of the array into the function parameter. This can avoid copying the whole array (the array may be longer than, so the copying cost will be great)

πŸŽ† Know null

Null means "null reference" in Java, that is, an invalid reference

public static void main(String[] args) {
        int[] arr = null;
        System.out.println(arr[0]);
    }

  The function of NULL is similar to that of NULL (NULL pointer) in C language. They all represent an invalid memory location. Therefore, no read-write operation can be performed on this memory. Once reading and writing is attempted, NullPointerException will be thrown

πŸŽ† First knowledge of JVM memory area division

A dormitory building will be divided into several different areas: freshmen, sophomores... Computer majors, communication majors... Memory is also similar. This large corridor is divided into many parts, and each area stores different data

PC register: only a small space to store the address of the next instruction to be executed

JVM stack: the key point is to store the local variable table (of course, there are other information). The reference to the storage address such as int[] arr we just created is saved here

Native method stack: the function of the native method stack is similar to that of the virtual machine stack. Only the saved contents are local variables of the native method. In some versions of JVM implementations (such as HotSpot), the native method stack and the virtual machine stack are together. Heap: the largest memory area managed by the JVM. Objects created with new are saved on the heap (for example, the previous new int[]{1, 2, 3})

Method area: used to store class information, constants, static variables, code compiled by the real-time compiler and other data that have been loaded by the virtual machine. The bytecode compiled by the method is saved in this area

Runtime constant pool: it is a part of the method area and stores literal (string constant) and symbol references. (note that since JDK 1.7, the runtime constant pool is on the heap)

Native method:

JVM is a program implemented based on C + +. In the process of Java program execution, it is essentially necessary to call some functions provided by C + + to interact with the underlying operating system. Therefore, some functions implemented by C + + will also be called in java development

The Native method here refers to these functions implemented in C + + and called by Java

πŸŽ† Array as the return value of the method

Code example: write a method to * 2 each element in the array

public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        transform(arr);
        printArray(arr);
    }
    public static void printArray(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
    public static void transform(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            arr[i] = arr[i] * 2;
        }
    }

Β 

πŸ™Œ   Two dimensional array

A two - dimensional array is essentially a one - dimensional array, but each element is a one - dimensional array

  Basic grammar

 data type[][] Array name = new data type [Number of rows][Number of columns] { Initialization data };
  public static void main5(String[] args) {
        int[][] array = {{1,2,3},{4,5,6}};
        int[][] array2 = new int[][]{{1,2,3},{4,5,6}};
        int[][] array3 = new int[2][3];
    }
 public static void main(String[] args) {
        int[][] array = {{1,2,3},{4,5,6}};
        /*System.out.println(array.length);
        System.out.println(array[0].length);*/
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array[i].length; j++) {
                System.out.print(array[i][j] +" ");
            }
            System.out.println();
        }
        System.out.println("================");
        for (int[] ret : array) {
            for (int x :ret) {
                System.out.print(x +" ");
            }
            System.out.println();
        }
        System.out.println("================");
        System.out.println(Arrays.deepToString(array));
    }

Β 

  ✨ Classes and objects

πŸ™Œ Preliminary cognition of class and object

C language is process oriented, focuses on the process, analyzes the steps to solve the problem, and gradually solves the problem through function call.

JAVA is based on object-oriented and focuses on objects. It divides one thing into different objects and completes it by the interaction between objects.

Process oriented focuses on the process, and the behavior involved in the whole process is function.

Object oriented focuses on the object, that is, the subject involved in the process, which connects the functional implementations through logic.

Process oriented: 1. Open the refrigerator 2. Put the elephant in the refrigerator 3. Close the refrigerator object oriented: opening, storing and closing the refrigerator are the operation of the refrigerator and the behavior of the refrigerator. The refrigerator is an object, so as long as the functions of the refrigerator are operated, they must be defined in the refrigerator.

[object oriented concept]

1. Object oriented is a way of thinking and an idea, such as concept and example, theory and practice, name and reality, etc.

2. A class is a general term for a class of objects. An object is an instance of the materialization of this class.

3. The benefits of object orientation: make complex things simple, just face an object.

[object oriented design]

Object oriented design holds an important experience: who owns the data and who provides external methods to operate the data (private) ((the passive party is the owner of the data and the active party is the executor)

During development: find objects, build objects, use objects, and maintain the relationship between objects.

Process oriented

  object-oriented

  πŸ™Œ Classes and instantiation of classes

πŸŽ† class

A class is a general term for a class of objects. An object is an instance of the materialization of this class.

Simple example: the model we use to make moon cakes is a class, through which we can make moon cakes. In this example, the class is the model and the moon cake is the object, so the moon cake is an entity. A model can instantiate countless objects.

In general: a class is equivalent to a template, and an object is a sample generated by the template. A class can generate countless objects.

Declaring a class is to create a new data type, and the class is a reference type in Java. Java uses the keyword class to declare the class. Let's see the following simple declaration of a class.

Basic grammar

// Create class
class <class_name>{  
    field;//Member properties
    method;//Member method
}
// Instantiate object
<class_name> <Object name> = new <class_name>();

Class is the keyword defining the class, ClassName is the name of the class, and {} is the body of the class.

The elements in the class are called: member attributes. The functions in the class are called: member methods.

Example:

class Person {
    public int age;//Member property instance variable
    public String name;
    public String sex;
    public void eat() {//Member method
       System.out.println("having dinner!");  
   }
    public void sleep() {
       System.out.println("sleep!");  
   }
}

πŸŽ† Class instantiation

The process of creating objects with class types is called class instantiation

Class instantiation the process of creating objects with class types is called class instantiation

1. A class is just a model that defines which members a class has.

2. A class can instantiate multiple objects. The instantiated objects occupy the actual physical space and store class member variables.

3. For example, instantiating an object by a class is like building a house by using an architectural design drawing in reality. A class is like a design drawing. It only designs what it needs, but there is no physical building. Similarly, a class is only a design. The instantiated object can actually store data and occupy physical space.

class Person {
    public int age;//Member property instance variable
    public String name;
    public String sex;
    public void eat() {//Member method
        System.out.println("having dinner!");
    }
    public void sleep() {
        System.out.println("sleep!");
    }
}
   class Main{
    public static void main(String[] args) {
        Person person = new Person();//Instantiate objects through new
        person.eat();//Member method calls need to be called by reference to the object
        person.sleep();
        //Generate object instantiation object
        Person person2 = new Person();
        Person person3 = new Person();
    }
}

matters needing attention

The new keyword is used to create an instance of an object

Use. To access properties and methods in an object

You can create multiple instances of the same class

class Person {
    //Ordinary member variables belong to objects
    private String name;
    private int age=19;
    //Static member variable - > class variable
    public static int count;//0
}

  πŸ™Œ Member of class

πŸŽ† Field / attribute / member variable

In the class, but the variables defined outside the method. Such variables are called "field" or "attribute" or "member variable" (all three names can be used, and generally they will not be strictly distinguished)

Used to describe what data a class contains

class Person {
    public String name;   // field
    public int age;
}
 
class Test {
    public static void main(String[] args) {
        Person person = new Person();
        System.out.println(person.name);
        System.out.println(person.age);
    }
}

Use. To access the fields of an object

Access includes both read and write

For the field of an object, if the initial value is not explicitly set, a default initial value will be set

Default value rule

For various numeric types, the default value is 0

For boolean types, the default value is false

For reference types (String, Array, and custom classes), the default value is null

Know null

Null is a "null reference" in Java, which means that no object is referenced. It is similar to a null pointer in C language. If NULL is operated on, an exception will be thrown

class Person {
    public String name;
    public int age;
}
class Test {
    public static void main(String[] args) {
        Person person = new Person();
        System.out.println(person.name.length());   // Get string length
    }
}

  Field local initialization

Many times, we don't want to use the default value for the field, but we need to explicitly set the initial value. It can be written as follows:

class Person {
    public String name = "Zhang San";
    public int age = 18;
}
class Test {
    public static void main(String[] args) {
        Person person = new Person();
        System.out.println(person.name);
        System.out.println(person.age);
    }
}

πŸŽ† Method

Used to describe the behavior of an object

class Person {
    public int age = 18;
    public String name = "Zhang San";
 
    public void show() {
        System.out.println("My name is" + name + ", this year" + age + "year");
    }
}
class Test {
    public static void main(String[] args) {
        Person person = new Person();
        person.show();
    }
}

  There is also a special method called   Construction method   When instantiating an object, the method will be automatically called. The method name is the same as the class name, which is used for object initialization. Although we have been able to initialize the attribute locally, some more complex initialization logic may be required, so the construction method can be used.

static keyword

1. Modification attribute

2. Modification method

3. Code block

4. Decoration class

a) Modifier attribute

Java static attributes are related to classes and not specific instances. In other words, different instances of the same class share the same static attribute

class TestDemo{
    public int a;
    public static int count;
}
class Main{
 
    public static void main(String[] args) {
        TestDemo t1 = new TestDemo();
        t1.a++;
        TestDemo.count++;
        System.out.println(t1.a);
        System.out.println(TestDemo.count);
        System.out.println("============");
        TestDemo t2 = new TestDemo();
        t2.a++;
        TestDemo.count++;
        System.out.println(t2.a);
        System.out.println(TestDemo.count);
    }
}

   count is modified by static and shared by all classes. And it does not belong to an object. The access method is: class name. Attribute.

  b) Modification method

If you apply the static keyword to any method, this method is called a static method.

Static methods belong to classes, not objects that belong to classes.

Static methods can be called directly without creating an instance of the class.

Static methods can access static data members and change the values of static data members.

class TestDemo{
    public int a;
    public static int count;
    public static void change() {
        count = 100;
        //a = 10; error non static data members cannot be accessed
    }
}
 class Main{
    public static void main(String[] args) {
        TestDemo.change();//Can be called without creating an instance object
        System.out.println(TestDemo.count);
    }
}

Note 1:

Static methods are independent of instances, but related to classes. Therefore, this leads to two situations:

Static methods cannot directly use non static data members or call non static methods (both non static data members and methods are instance related)

This and super keywords cannot be used in a static context (this is the reference of the current instance, super is the reference of the parent instance of the current instance, and is also related to the current instance)
Β 

Note 2:

Static is added to all the methods we have written for simplicity. But in fact, whether a method needs static or not depends on the situation. The main method is a static method

πŸŽ† Summary

class Person {
    public int age;//Instance variables are stored in objects
    public String name;//Instance variable
    public String sex;//Instance variable
    public static int count;//Class variables are also called static variables. They have been generated during compilation. They belong to the class itself and have only one copy. Store in method area
    public final int SIZE = 10;//What is modified by final is called a constant, which also belongs to an object. It is modified by final and cannot be changed later
    public static final int  COUNT = 99;//Static constants belong to the class itself. Only one is modified by final and cannot be changed later
    //Instance member function
    public void eat() {
        int a = 10;//local variable
        System.out.println("eat()!");
    }
    //Instance member function
    public void sleep() {
        System.out.println("sleep()!");
    }
    //Static member function
    public static void staticTest(){
        //Non static members cannot be accessed
        //sex = "man"; error
        System.out.println("StaticTest()");
    }
}
 class Main{
    public static void main(String[] args) {
        //Generate object instantiation object
        Person person = new Person();//person is a reference to the object
        System.out.println(person.age);//The default value is 0
        System.out.println(person.name);//The default value is null
        //System.out.println(person.count);// There will be a warning!
        //Correct access method:
        System.out.println(Person.count);
        System.out.println(Person.COUNT);
        Person.staticTest();
        //Summary: all methods or properties modified by static do not depend on objects.
        person.eat();
        person.sleep();
    }
}

Β 

πŸ™Œ   encapsulation  

What is encapsulation?

>The beginning is to discuss a problem: the essence of software development is the management of program complexity. If the complexity of a software code is too high, it can not continue to maintain. How to manage complexity? Encapsulation is the most basic method

When we write code, we often involve two roles: class implementer and class caller

The essence of encapsulation is that the caller of a class does not have to know much about how the class implementer implements the class, as long as he knows how to use the class

This reduces the learning and use cost of class users, thus reducing the complexity

πŸŽ† private implementation encapsulation

The two keywords private/ public represent "access control"

Member variables or member methods modified by public can be directly used by class callers

The member variable or member method modified by private cannot be used by the caller of the class

  In other words, the user of a class does not need to know or pay attention to the private members of a class, so that the class caller can use the class at a lower cost

Use public directly

class Person {
    public String name = "Zhang San";
    public int age = 18;
}
class Test {
    public static void main(String[] args) {
        Person person = new Person();
        System.out.println("My name is" + person.name + ", this year" + person.age + "year");
    }
}

This kind of code makes the user of the class (the code of the main method) have to understand the internal implementation of the Person class before they can use this class. The learning cost is high. Once the implementer of the class modifies the code (for example, changing the name to myName), the user of the class needs to modify his own code on a large scale, and the maintenance cost is high

class Person {
    private String name = "Zhang San";
    private int age = 18;
 
    public void show() {
        System.out.println("My name is" + name + ", this year" + age + "year");
    }
}
class Test {
    public static void main(String[] args) {
        Person person = new Person();
        person.show();
    }
} 

At this time, the field has been decorated with private. The caller of the class (in the main method) cannot use it directly. Instead, it needs to use the show method. At this time, the user of the class does not need to know the implementation details of the Person class

At the same time, if the implementer of the class modifies the name of the field, the caller of the class does not need to make any modification (the caller of the class cannot access fields such as name and age at all)

matters needing attention

Private can not only modify fields, but also modify methods. Generally, we will set fields as private attributes, but whether methods need to be set to public depends on the specific situation. Generally, we want a class to provide only "necessary" public methods, rather than setting all methods to public.

πŸŽ† getter and setter methods

When we use private to decorate a field, we can't use this field directly

Code example

class Person {
    private String name = "Zhang San";
    private int age = 18;
 
    public void show() {
        System.out.println("My name is" + name + ", this year" + age + "year");
    }
}
class Test {
    public static void main(String[] args) {
        Person person = new Person();
        person.age = 20;
        person.show();
    }
} 

  Code example

class Person {
    private String name;//Instance member variable
    private int age;
 
    public void setName(String name){
        //name = name;// You can't write that
        this.name = name;//this reference represents the object that calls the method
    }
    public String getName(){
        return name;
    }
 
    public void show(){
        System.out.println("name: "+name+" age: "+age);
    }
 
    public static void main(String[] args) {
        Person person = new Person();
        person.setName("caocao");
        String name = person.getName();
        System.out.println(name);
        person.show();
    }
}

matters needing attention

getName is the getter method, which means to get the value of this member

setName is the setter method, which means to set the value of this member

When the formal parameter name of the set method is the same as the name of the member attribute in the class, if this is not used, it is equivalent to self assignment. This represents the reference of the current instance

Not all fields must provide setter / getter methods, but which method to provide should be determined according to the actual situation. In IDEA, you can use alt + insert (or alt + F12) to quickly generate setter / getter methods

In VSCode, you can use the right mouse button menu - > source code operation to automatically generate setter / getter methods
Β 

  πŸ™Œ Construction method  

πŸŽ† Basic grammar

Constructor is a special method. When instantiating a new object with the keyword new, it will be called automatically to complete the initialization operation

new execution process

Allocate memory space for objects

Call the constructor of the object

rule of grammar

1. The method name must be the same as the class name

2. The constructor has no return value type declaration

3. There must be at least one construction method in each class (if there is no clear definition, the system will automatically generate a parameterless construction)

matters needing attention

If no constructor is provided in the class, the compiler generates a constructor without parameters by default

If a constructor is defined in a class, the default parameterless constructor will no longer be generated

The construction method supports overloading. The rules are consistent with the overloading of ordinary methods

Code example

class Person {
 
    private String name;//Instance member variable
    private int age;
    private String sex;
    //Default constructor construction object
    public Person() {
        this.name = "caocao";
        this.age = 10;
        this.sex = "male";
    }
    //Constructor with 3 arguments
    public Person(String name,int age,String sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }
    public void show(){
        System.out.println("name: "+name+" age: "+age+" sex: "+sex);
    }
 
}
 class Main{
    public static void main(String[] args) {
        Person p1 = new Person();//Call the constructor without parameters. If the program does not provide it, it will call the constructor without parameters
        p1.show();
        Person p2 = new Person("zhangfei",80,"male");//Call the constructor with 3 parameters
        p2.show();
    }
}

  πŸŽ† this keyword

This indicates the current object reference (note that it is not the current object). You can use this to access the fields and methods of the object

class Person {
    private String name;//Instance member variable
    private int age;
    private String sex;
 
    //Default constructor construction object
    public Person() {
        //this calls the constructor
        this("bit", 12, "man");//It must be displayed on the first line
    }
 
    //The relationship between these two constructors is overloaded.
    public Person(String name,int age,String sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }
    public void show() {
        System.out.println("name: "+name+" age: "+age+" sex: "+sex);
    }
}
 class Main {
    public static void main(String[] args) {
        Person person = new Person();//Calling a constructor without parameters
        person.show();
    }
}

  We will find that inside the constructor, we can use the this keyword. The constructor is used to construct the object. Before the object is constructed, we use this. Does this still represent the current object? Of course not. This represents the reference of the current object.

πŸ™Œ Recognize code blocks

πŸŽ† What is a code block

Fields are initialized in the following ways:

1. Local initialization

2. Initialize using the construction method

3. Initialize with code block

πŸŽ† Common code block

 class Main{
    public static void main(String[] args) {
        { //Directly use {} definition, common method block
            int x = 10 ;
            System.out.println("x1 = " +x);
        }
        int x = 100 ;
        System.out.println("x2 = " +x);
    }
}

  πŸŽ† Construct code block  

class Person{
    private String name;//Instance member variable
    private int age;
    private String sex;
    public Person() {
        System.out.println("I am Person init()!");
    }
    //Instance code block
    {
        this.name = "bit";
        this.age = 12;
        this.sex = "man";
        System.out.println("I am instance init()!");
    }
    public void show(){
        System.out.println("name: "+name+" age: "+age+" sex: "+sex);
    }
}
 class Main {
    public static void main(String[] args) {
        Person p1 = new Person();
        p1.show();
    }
}

  πŸŽ† Static code block

class Person{
    private String name;//Instance member variable
    private int age;
    private String sex;
    private static int count = 0;//Static member variables are shared by classes in the data method area
    public Person(){
        System.out.println("I am Person init()!");
    }
    //Instance code block
    {
        this.name = "bit";
        this.age = 12;
        this.sex = "man";
        System.out.println("I am instance init()!");
    }
    //Static code block
    static {
        count = 10;//Only static data members can be accessed
        System.out.println("I am static init()!");
    }
    public void show(){
        System.out.println("name: "+name+" age: "+age+" sex: "+sex);
    }
}
 class Main {
    public static void main(String[] args) {
        Person p1 = new Person();
        Person p2 = new Person();//Will static code blocks still be executed?
    }
}

matters needing attention

No matter how many objects are generated, the static code block will be executed only once and first.

After the static code block is executed, the instance code block (construction block) is executed, and then the constructor is executed.

πŸ™Œ Supplementary notes

πŸŽ† toString method

class Person {
    private String name;
    private int age;
    public Person(String name,int age) {
        this.age = age;
        this.name = name;
    }
    public void show() {
        System.out.println("name:"+name+" " + "age:"+age);
    }
}
 class Main {
    public static void main(String[] args) {
        Person person = new Person("caocao",19);
        person.show();
        //We found that the hash value of an address is printed here. The reason: the toString method of Object is called
        System.out.println(person);
    }
}

  You can use methods like toString to automatically convert objects to strings

class Person {
    private String name;
    private int age;
    public Person(String name,int age) {
        this.age = age;
        this.name = name;
    }
    public void show() {
        System.out.println("name:"+name+" " + "age:"+age);
    }
    //Override the toString method of Object
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
 class Main {
    public static void main(String[] args) {
        Person person = new Person("caocao",19);
        person.show();
        System.out.println(person);
    }
}

Β 

matters needing attention:

The toString method will be called automatically at println

The operation of converting an object into a string is called serialization

ToString is the method provided by the Object class. The Person class created by us inherits from the Object class by default. We can override toString method to implement our own version of conversion string method. (we will focus on the concepts of inheritance and rewriting later.)

@Override is called "Annotation" in Java. Here @ override means that the toString method implemented below overrides the method of the parent class. The following courses will introduce annotation in detail

πŸŽ† Anonymous object

Objects that are not referenced are called anonymous objects

Anonymous objects can only be used when creating objects

If an object is used only once and does not need to be used later, consider using anonymous objects

class Person {
    private String name;
    private int age;
    public Person(String name,int age) {
        this.age = age;
        this.name = name;
    }
    public void show() {
        System.out.println("name:"+name+" " + "age:"+age);
    }
}
class Main {
    public static void main(String[] args) {
        new Person("caocao",19).show();//Calling methods through anonymous objects
    }
}

  πŸ™Œ Summary of key contents

A class can produce countless objects. A class is a template and an object is a concrete instance.

The attributes defined in class can be roughly divided into several categories: class attributes and object attributes. The data attributes modified by static are called class attributes, and the methods modified by static are called class methods. The feature is that they do not depend on objects. We can call their attributes or methods only through the class name.

Static code block takes precedence over instance code block, and instance code block takes precedence over constructor.

this keyword represents the reference of the current object. Is not the current object.

  ✨ object-oriented

πŸ™Œ package

πŸŽ† summary

Package   Is a way to organize classes

The main purpose of using packages is to ensure the uniqueness of classes

For example, you write a Test class in your code. Then your colleagues may also write a Test class. If two classes with the same name appear, they will conflict and the code will not compile

πŸŽ† Import classes in package

Java has provided many ready-made classes for us to use. For example

public class TextDemo {
    public static void main(String[] args) {
        java.util.Date date = new java.util.Date();
        // Get a millisecond timestamp
        System.out.println(date.getTime());
    }
}

have access to   java.util.Date   In this way, the functions in the Java. Util package are introduced   Date   Class. However, this writing method is more troublesome. You can use the import statement to import the package

import java.util.Date;
    public class Test {
    public static void main(String[] args) {
        Date date = new Date();
        // Get a millisecond timestamp
        System.out.println(date.getTime());
    }
}

   If required   java.util   Other classes in can be used   import java.util.*

import java.util.*;
public class Test {
    public static void main(String[] args) {
        Date date = new Date();
        // Get a millisecond timestamp
        System.out.println(date.getTime());
   }
}

However, we prefer to explicitly specify the class name to be imported. Otherwise, it is still prone to conflict

import java.util.*;
import java.sql.*;
public class Test {
    public static void main(String[] args) {
        // There is a class such as Date in util and sql. At this time, ambiguity will occur and compilation error will occur
        Date date = new Date();
        System.out.println(date.getTime());
    }
}

   In this case, you need to use the full class name

import java.util.*;
import java.sql.*;
public class Test {
    public static void main(String[] args) {
        java.util.Date date = new java.util.Date();
        System.out.println(date.getTime());
   }
}

Note: import and C + +  # include   There is a big difference. C + + must #include to introduce other file contents, but Java does not need it. Import is just to make it easier to write code. Import is more similar to C + +   namespace   and   using

πŸŽ† Static import

Use import static to import static methods and fields in a package

import static java.lang.System.*;
public class Test {
    public static void main(String[] args) {
        out.println("hello");
   }
}

In this way, it is more convenient to write some code, such as

import static java.lang.Math.*;
public class Test {
    public static void main(String[] args) {
        double x = 30;
        double y = 40;
        // Static import is more convenient to write 
        // double result = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
        double result = sqrt(pow(x, 2) + pow(y, 2));
        System.out.println(result);
   }
}

πŸ™Œ Putting classes in packages

πŸŽ† Basic rules

Add a package statement at the top of the file to specify which package the code is in

The package name should be specified as a unique name as far as possible, usually in the inverted form of the company's domain name (e.g. com.bit.demo1)

The package name should match the code path. For example, if you create a package of com.bit.demo1, there will be a corresponding path com/bit/demo1 to store the code

If a class does not have a package statement, the class is placed in a default package

πŸŽ† Operation steps

1) Create a new package in IDEA: right click SRC - > New - > package

2) Enter the package name in the pop-up dialog box, such as demo1

3) Create a class in the package, right-click package name - > New - > class, and then enter the class name

  4) At the same time, we can see that a package statement appears at the top of the newly created Test.java file

  πŸ™Œ Access control for packages

We have learned about public and private in the class. Members in private can only be used inside the class. If a member does not contain public and private keywords, the member can be used in other classes inside the package, but not in classes outside the package

The following code gives an example. Demo1 and Demo2 are in the same package, and Test is in other packages

Demo1.java

package com.bit.demo;
public class Demo1 {
    int value = 0;
}

Demo2.java

package com.bit.demo; 
public class Demo2 { 
    public static void main(String[] args) { 
    Demo1 demo = new Demo1(); 
    System.out.println(demo.value); 
 } 
} 

Β Test.java

package com.bit.demo; 
public class Demo2 { 
   public static void main(String[] args) { 
   Demo1 demo = new Demo1(); 
   System.out.println(demo.value); 
 } 
} 

 // Compilation Error:(6, 32) java: value is not public in com.bit.demo.Demo1; It cannot be accessed from an external package

πŸŽ† Common system packages

1. java.lang: system common basic classes (String, Object). This package is automatically imported from JDK1.1.

2. java.lang.reflect:java reflection programming package;

3. java.net: network programming development package.

4. java.sql: support package for database development.

5. java.util: a tool package provided by java. (collection class, etc.) is very important

6. java.io:I/O programming development kit.

πŸ™Œ inherit

πŸŽ† background

Classes created in the code are mainly used to abstract some things (including attributes and methods) in reality. Sometimes there are some associations between objective things, so there will be some associations when expressed as classes and objects

For example, design a class to represent animals

Note that we can create a separate java file for each class. The class name must match the. Java file name (case sensitive)

// Animal.java 
public class Animal { 
   public String name; 
   public Animal(String name) { 
   this.name = name; 
 } 
 
   public void eat(String food) { 
   System.out.println(this.name + "I am eating" + food); 
 } 
} 
// Cat.java 
class Cat { 
   public String name; 
   public Cat(String name) { 
   this.name = name; 
 } 
 
   public void eat(String food) { 
   System.out.println(this.name + "I am eating" + food); 
 } 
} 
// Bird.java 
class Bird { 
   public String name; 
   public Bird(String name) { 
   this.name = name; 
 } 
 
   public void eat(String food) { 
   System.out.println(this.name + "I am eating" + food); 
 } 
 
   public void fly() { 
   System.out.println(this.name + "Flying οΈΏ(οΏ£οΈΆοΏ£)οΈΏ"); 
 } 
} 

In this code, we found a lot of redundant code

After careful analysis, we find that Animal is related to Cat and Bird:

All three classes have the same eat method and behave exactly the same

All three classes have the same name attribute and have exactly the same meaning

Logically, Cat and Bird are both Animal (is - a semantics)

At this time, inherited classes such as Animal are called parent classes, base classes or superclasses. For classes such as Cat and Bird, we are called subclasses. Derived classes are similar to real sons inheriting their father's property. Subclasses will also inherit the fields and methods of the parent class to achieve the effect of code reuse

πŸ™Œ rule of grammar

πŸŽ† Basic grammar

class Subclass extends Parent class { 
 
} 

Use extends to specify the parent class

A subclass in Java can only inherit one parent class (while languages such as C++/Python support multiple inheritance)

Subclasses inherit all public fields and methods of the parent class

private fields and methods of the parent class are inaccessible in subclasses

The instance of a subclass also contains the instance of the parent class. You can use the super keyword to get a reference to the instance of the parent class

The above code can be improved by inheritance. At this time, we let Cat and Bird inherit from the Animal class, so Cat does not have to write the name field and eat method when defining

class Bird extends Animal { 
   public Bird(String name) { 
   super(name); 
 } 
   public void fly() { 
   System.out.println(this.name + "Flying οΈΏ(οΏ£οΈΆοΏ£)οΈΏ"); 
 } 
} 
public class Test { 
   public static void main(String[] args) { 
   Cat cat = new Cat("Xiao Hei"); 
   cat.eat("Cat food"); 
   Bird bird = new Bird("round"); 
   bird.fly(); 
  } 
} 

If we change the name to private, the subclass cannot be accessed at this time

class Bird extends Animal { 
   public Bird(String name){ 
   super(name); 
 } 
   public void fly() { 
   System.out.println(this.name + "Flying οΈΏ(οΏ£οΈΆοΏ£)οΈΏ"); 
 } 
} 
// Compilation error
Error:(19, 32) java: name stay Animal Medium is private access control 

πŸŽ† protected keyword

Just now, we found that if the field is set to private, the subclass cannot be accessed. However, setting it to public violates our original intention of "encapsulation". The best way to achieve the best of both worlds is the protected keyword

The fields and methods modified by protected are inaccessible to the caller of the class

For subclasses of classes and other classes in the same package, the fields and methods modified by protected are accessible

// Animal.java 
public class Animal { 
   protected String name; 
   public Animal(String name) {
   this.name = name; 
 } 
   public void eat(String food) { 
   System.out.println(this.name + "I am eating" + food); 
 } 
} 
// Bird.java 
public class Bird extends Animal { 
   public Bird(String name){ 
   super(name); 
 } 
   public void fly() { 
 // For the protected field of the parent class, the child class can access it correctly
   System.out.println(this.name + "Flying οΈΏ(οΏ£οΈΆοΏ£)οΈΏ"); 
 } 
} 
// Test.java and Animal.java are not in the same package 
public class Test { 
   public static void main(String[] args) { 
   Animal animal = new Animal("Small animals"); 
   System.out.println(animal.name); // There is a compilation error at this time. name cannot be accessed 
 } 
}

Summary: there are four access permissions for fields and methods in Java

private: it can be accessed inside the class, but not outside the class

Default (also called package access permission): it can be accessed inside a class. Classes in the same package can be accessed, but other classes cannot

protected: it can be accessed inside a class. Subclasses and classes in the same package can be accessed. Other classes cannot be accessed

public: both inside the class and the caller of the class can access it

  πŸŽ† More complex inheritance relationships

// Animal.java 
public Animal { 
 ... 
} 
// Cat.java 
public Cat extends Animal { 
 ... 
} 
// ChineseGardenCat.java 
public ChineseGardenCat extends Cat { 
 ... 
} 
// OrangeCat.java 
public Orange extends ChineseGardenCat { 
 ... 
} 
...... 

The inheritance method just now is called multi-layer inheritance, that is, subclasses can further derive new subclasses

Always bear in mind that the classes we write are abstractions of real things. However, the projects we really encounter in the company often have complex business and may involve a series of complex concepts, which need to be represented by code. Therefore, there will be many classes written in our real projects, and the relationship between classes will be more complex

But even so, we don't want the inheritance levels between classes to be too complex. Generally, we don't want more than three-tier inheritance relationships. If there are too many inheritance levels, we need to consider refactoring the code. If you want to restrict inheritance from syntax, you can use the final keyword

πŸŽ† final keyword

We once learned that when the final keyword modifies a variable or field, it represents a constant (which cannot be modified)

final int a = 10; 
a = 20; // Compilation error

The final keyword can also modify a class, which means that the modified class cannot be inherited

final public class Animal { 
 ... 
} 
public class Bird extends Animal { 
 ... 
} 
// Compilation error
Error:(3, 27) java: Unable to start from the final com.bit.Animal Inherit

The function of the final keyword is to restrict the class from being inherited, which means "inflexible"

In programming, flexibility is often not a good thing. Flexibility may mean more error prone

When a class decorated with final is inherited, it will compile and report an error. At this time, it can prompt us that such inheritance is contrary to the original intention of the class design

πŸ™Œ combination

Similar to inheritance, composition is also a way to express the relationship between classes and achieve the effect of code reuse. For example, it represents a school:

public class Student { 
 ... 
} 
public class Teacher { 
 ... 
} 
public class School { 
 public Student[] students; 
 public Teacher[] teachers; 
} 

Composition does not involve special syntax (keywords such as extensions), but only takes an instance of one class as a field of another class. This is one of the common ways we design classes

Combinatorial representation has - a semantics

In the example just now, we can understand that a school "contains" several students and teachers

Inheritance represents is - a semantics

In the above example of "animals and cats", we can understand that a cat is also "an animal"

πŸ™Œ polymorphic

πŸŽ† Upward transformation

In the example just now, we wrote the following code

Bird bird = new Bird("round");

This code can also be written like this

At this time, bird2 is a reference to a parent class (Animal) and points to an instance of a child class (Bird). This writing is called upward transformation

Why is "upward transformation"?

In object-oriented programming, for some complex scenarios (many classes, very complex inheritance relationships), the program ape will draw a UML diagram to represent the relationship between classes. At this time, the parent class is usually drawn above the child class. Therefore, we call it "upward transformation" to show the direction of the parent class

Method transmission parameter

public class Test { 
   public static void main(String[] args) { 
   Bird bird = new Bird("round"); 
   feed(bird); 
 } 
   public static void feed(Animal animal) { 
   animal.eat("millet"); 
 } 
} 
 
// results of enforcement
 Yuanyuan is eating millet

At this time, the type of formal parameter Animal is Animal (base class), which actually corresponds to the instance of Bird (parent class)

Method return

public class Test { 
   public static void main(String[] args) { 
   Animal animal = findMyAnimal(); 
 } 
   public static Animal findMyAnimal() { 
   Bird bird = new Bird("round"); 
   return bird; 
 } 
} 

At this time, the method findMyAnimal returns a reference of Animal type, but actually corresponds to the instance of Bird

public class Test { 
   public static void main(String[] args) { 
   Animal animal = findMyAnimal(); 
 } 
   public static Animal findMyAnimal() { 
   Bird bird = new Bird("round"); 
   return bird; 
 } 
} 

At this time, the method findMyAnimal returns a reference of Animal type, but actually corresponds to the instance of Bird

πŸŽ† Dynamic binding

What happens when a method with the same name appears in the subclass and parent class? Modify the previous code slightly, add the eat method with the same name to the Bird class, and add different logs in the two eat

// Animal.java 
public class Animal { 
    protected String name; 
    public Animal(String name) { 
    this.name = name; 
 } 
    public void eat(String food) { 
    System.out.println("I am a small animal"); 
    System.out.println(this.name + "I am eating" + food); 
 }
}
// Bird.java 
public class Bird extends Animal { 
   public Bird(String name) { 
   super(name); 
 } 
   public void eat(String food) { 
   System.out.println("I am a bird"); 
   System.out.println(this.name + "I am eating" + food); 
 } 
}
// Test.java 
public class Test { 
   public static void main(String[] args) { 
   Animal animal1 = new Animal("round"); 
   animal1.eat("millet"); 
   Animal animal2 = new Bird("flat "); 
   animal2.eat("millet"); 
 } 
} 

//Execution results
I am a small animal
Yuanyuan is eating millet
I am a bird
Bian Bian is eating millet

At this point, we find that:

Although both animal1 and animal2 are references of Animal type, animal1 points to instances of Animal type and animal2 points to instances of Bird type

Call eat methods for animal1 and animal2 respectively. It is found that animal1.eat() actually calls the methods of the parent class, while animal2.eat() actually calls the methods of the child class

Therefore, in Java, which code (which is the code of the parent class method or the code of the subclass method) is executed by calling a class method, depends on whether the reference refers to the parent object or the subclass object. This procedure is determined by the program runtime (instead of the compile period), so it is called   Dynamic binding

πŸŽ† Method rewrite

For the eat method just now: the subclass implements the method with the same name as the parent class, and the type and number of parameters are exactly the same. This is called   Override / override

Notes on rewriting

1. Rewriting and overloading are completely different  

2. Ordinary methods can be overridden, but static methods modified by static cannot be overridden

3. The access permission of the method overriding the subclass cannot be lower than that of the parent class

4. The return value type of the overridden method may not be the same as that of the parent class (but it is recommended to write it the same, except in special cases)

Example of method permission: change eat of subclass to private

// Animal.java 
public class Animal { 
 public void eat(String food) { 
 ... 
 } 
} 
// Bird.java 
public class Bird extends Animal { 
 // Change the eat of the subclass to private 
 private void eat(String food) { 
 ... 
 } 
} 
// Compilation error
//Error: (8, 10) eat(java.lang.String) in Java: com.bit.bird cannot overwrite eat(java.lang.String) in com.bit.Animal
//eat(java.lang.String) 
// Attempting to assign lower access rights; Previously public

In addition, for overridden methods, you can use the @ Override annotation to specify them explicitly

// Bird.java 
public class Bird extends Animal { 
 @Override 
 private void eat(String food) { 
 ... 
 } 
} 

With this annotation, we can check the validity. For example, if we accidentally misspell the method name (for example, write aet), the compiler will find that there is no aet method in the parent class, and an error will be compiled, indicating that it cannot constitute rewriting. We recommend that we explicitly add it when rewriting the method in the code  @ Override annotation

Summary:   The difference between overloading and rewriting

  In fact, method rewriting is a rule at the Java syntax level, and dynamic binding is the underlying implementation of the syntax rule of method rewriting. They essentially describe the same thing, but have different emphases

πŸŽ† Understanding polymorphism

With face up transformation, dynamic binding and method rewriting, we can use   Polymorphism   We can write some code that only focuses on the parent class, which can be compatible with various subclasses at the same time

Code example:   Print multiple shapes

class Shape { 
 public void draw() { 
 // Don't do anything
 } 
}
class Cycle extends Shape { 
  @Override 
  public void draw() { 
  System.out.println("β—‹"); 
 } 
} 
class Rect extends Shape { 
  @Override 
  public void draw() { 
  System.out.println("β–‘"); 
 } 
} 
class Flower extends Shape { 
   @Override 
   public void draw() { 
   System.out.println("♣"); 
 } 
} 
// Test.java 
public class Test { 
   public static void main(String[] args) { 
   Shape shape1 = new Flower(); 
   Shape shape2 = new Cycle(); 
   Shape shape3 = new Rect(); 
   drawMap(shape1); 
   drawMap(shape2); 
   drawMap(shape3); 
 }
// Print a single drawing
 public static void drawShape(Shape shape) { 
 shape.draw(); 
 } 
} 

When the caller of a class writes the drawMap method, the parameter type is shape (parent class). At this time, he does not know or pay attention to the instance of which type (subclass) the current shape reference refers to. At this time, the reference of shape may call the draw method in many different ways (related to the instance corresponding to shape), This behavior is called polymorphism

What are the benefits of using polymorphism?

1) The cost of using classes by class callers is further reduced

Encapsulation means that the caller of a class does not need to know the implementation details of the class

Polymorphism allows the caller of a class not to know what the type of the class is, but to know that the object has a method

Therefore, polymorphism can be understood as a further encapsulation, which further reduces the use cost of class callers

2) It can reduce the "loop complexity" of the code and avoid using a lot of if - else

public static void drawShapes() { 
    Rect rect = new Rect(); 
    Cycle cycle = new Cycle(); 
    Flower flower = new Flower(); 
    String[] shapes = {"cycle", "rect", "cycle", "rect", "flower"}; 
 
 for(String shape : shapes) { 
 if(shape.equals("cycle")) { 
    cycle.draw(); 
 } else if (shape.equals("rect")) { 
    rect.draw(); 
 } else if (shape.equals("flower")) { 
    flower.draw(); 
 } 
 } 
} 

If polymorphism is used, there is no need to write so many if - else branch statements, and the code is simpler

public static void drawShapes() { 
   // We created an array of Shape objects 
   Shape[] shapes = {new Cycle(), new Rect(), new Cycle(), 
   new Rect(), new Flower()}; 
   for (Shape shape : shapes) { 
   shape.draw(); 
 } 
} 

What is "circle complexity"?

Circle complexity is a way to describe the complexity of a piece of code. If a piece of code is flat and straightforward, it is relatively simple and easy to understand. If there are many conditional branches or loop statements, it is considered more complex to understand

Therefore, we can simply and roughly calculate the number of conditional statements and loop statements in a piece of code. This number is called "cycle complexity". If the cycle complexity of a method is too high, refactoring needs to be considered

3) More scalable

If you want to add a new shape, the code change cost is low by using polymorphism

class Triangle extends Shape { 
   @Override 
   public void draw() { 
   System.out.println("β–³"); 
 } 
}

For the caller of a class (drawShapes method), just create an instance of a new class, and the change cost is very low. For the case where polymorphism is not used, it is necessary to modify the if - else in drawShapes, and the change cost is higher

πŸŽ† Downward transformation

Upward transformation is the transformation of a child object into a parent object, and downward transformation is the transformation of a parent object into a child object. Compared with upward transformation, downward transformation is less common, but it also has certain uses

// Animal.java 
public class Animal { 
   protected String name; 
   public Animal(String name) { 
   this.name = name; 
 } 
   public void eat(String food) { 
   System.out.println("I am a small animal"); 
   System.out.println(this.name + "I am eating" + food); 
 } 
} 
// Bird.java 
public class Bird extends Animal { 
   public Bird(String name) { 
   super(name); 
 } 
   public void eat(String food) { 
   System.out.println("I am a bird"); 
   System.out.println(this.name + "I am eating" + food); 
 }
public void fly() { 
   System.out.println(this.name + "Flying");
   }
}

πŸŽ† super keyword

In the previous code, due to the rewriting mechanism, the methods of the subclass are called. What if you need to call the parent method inside the subclass? You can use the super keyword

super means to get the reference of the parent class instance. It involves two common usages

1) super is used to call the constructor of the parent class (this code has been written earlier)

public Bird(String name) { 
 super(name); 
} 

2) Use super to call the normal methods of the parent class

public class Bird extends Animal { 
   public Bird(String name) { 
   super(name); 
 } 
   @Override 
   public void eat(String food) { 
   // Modify the code so that the child calls the interface of the parent class 
   super.eat(food); 
   System.out.println("I am a bird"); 
   System.out.println(this.name + "I am eating" + food); 
 } 
} 

In this code, if you directly call eat (without super) in the eat method of the subclass, it is considered to call the eat of the subclass itself (that is, recursion). Adding the super keyword is the method of calling the parent class

be careful   The functions of super and this are somewhat similar, but we should pay attention to the differences

πŸŽ† Method of calling rewriting in construction method

class B { 
 public B() { 
    // do nothing 
    func(); 
 } 
    public void func() { 
    System.out.println("B.func()"); 
 } 
}
class D extends B { 
   private int num = 1; 
   @Override 
   public void func() { 
   System.out.println("D.func() " + num); 
 } 
} 
public class Test { 
   public static void main(String[] args) { 
   D d = new D(); 
   }
}

When constructing D object, B's construction method will be called

The func method is called in the construction method of B, which triggers dynamic binding and calls to func in D.

At this time, the D object itself has not been constructed, and num is in an uninitialized state with a value of 0

Conclusion:   "Make objects into a working state as simple as possible". Try not to call the method in the constructor. If this method is rewritten by child class, it will trigger dynamic binding, but at this time the subclass object has not been constructed yet, some hidden but extremely difficult problems may appear.

πŸŽ† summary

Polymorphism is a difficult part of object-oriented programming. We will further experience the use of polymorphism in the following abstract classes and interfaces. The focus is on the coding benefits brought by polymorphism

On the other hand, if you put aside Java, polymorphism is actually a broader concept, which is not necessarily related to the syntax of "inheritance"

The "dynamic polymorphism" in C + + is similar to that in Java. However, C + + also has a "static polymorphism" (template), which has nothing to do with the inheritance system

Polymorphism in Python embodies "duck type" and has nothing to do with inheritance system

There is no concept of "inheritance" in Go language, which can also express polymorphism

πŸ™Œ abstract class

πŸŽ† rule of grammar

In the example of printing graphics just now, we found that the draw method in the parent class Shape does not seem to have any actual work. The main drawing graphics are completed by the draw methods of various subclasses of Shape. Like this method without actual work, we can design it as an abstract method. The class containing abstract methods is called abstract class (abstract class)

abstract class Shape { 
 abstract public void draw(); 
}

Add the abstract keyword before the draw method to indicate that it is an abstract method. At the same time, the abstract method has no method body (without {}, it cannot execute concrete code)

For a class containing abstract methods, the abstract keyword must be added to indicate that it is an abstract class

matters needing attention

1) Abstract classes cannot be instantiated directly

Shape shape = new Shape(); 
// Compilation error
//Error:(30, 23) java: Shape is abstract; Cannot instantiate

2) Abstract methods cannot be private

abstract class Shape { 
 abstract private void draw(); 
} 
// Compilation error
//Error:(4, 27) java: illegal modifier combination: abstract and private 

3) Abstract classes can contain other non abstract methods or fields. The rules of this non abstract method are the same as those of ordinary methods. It can be overridden or called directly by subclasses

abstract class Shape { 
   abstract public void draw(); 
   void func() { 
   System.out.println("func"); 
 } 
} 
  class Rect extends Shape { 
   ... 
} 
public class Test { 
  public static void main(String[] args) { 
  Shape shape = new Rect(); 
  shape.func(); 
 } 
} 
// results of enforcement
//func

πŸŽ† Role of abstract classes

Abstract classes exist in order to be inherited

The abstract class itself cannot be instantiated. If you want to use it, you can only create a subclass of the abstract class. Then let the subclass override the abstract methods in the abstract class

πŸ™Œ Interface

An interface is a further step of an abstract class. An abstract class can also contain non abstract methods and fields. While the methods contained in an interface are abstract methods, and fields can only contain static constants

πŸŽ† rule of grammar

In the example of printing graphics just now, our parent class Shape does not contain other non abstract methods, and can also be designed as an interface

interface IShape { 
   void draw(); 
} 
class Cycle implements IShape { 
   @Override 
   public void draw() { 
   System.out.println("β—‹"); 
 } 
} 
public class Test { 
   public static void main(String[] args) { 
   IShape shape = new Rect(); 
   shape.draw(); 
 } 
} 

Define an interface using interface

The methods in the interface must be abstract methods, so abstract can be omitted

The methods in the interface must be public, so public can be omitted

Cycle uses implements to inherit the interface. At this time, the meaning expressed is no longer "extension", but "implementation"

When calling, you can also create an interface reference corresponding to an instance of a subclass

Interfaces cannot be instantiated alone

Extensions vs. implementations

Extension refers to the further expansion of functions when certain functions already exist

Implementation means that there is nothing at present and needs to be constructed from scratch

An interface can only contain abstract methods. For fields  , Interface can only contain final static

interface IShape { 
   void draw(); 
   public static final int num = 10; 
} 

The public, static and final keywords can be omitted. The omitted num still represents the public static constant

1. When we create an interface, the name of the interface generally starts with the capital letter I

2. The naming of the interface generally uses the word of "adjective"

3. Alibaba code specification stipulates that methods and attributes in the interface should not be decorated with any symbols to keep the code concise

πŸŽ† Implement multiple interfaces

Sometimes we need to make a class inherit from multiple parent classes at the same time. This is done in some programming languages   Multiple inheritance   However, Java only supports single inheritance, and a class can only extend one parent class. However, multiple interfaces can be implemented at the same time, and the similar effect of multiple inheritance can be achieved. Now we represent a group of animals through classes

class Animal { 
  protected String name; 
 
  public Animal(String name) { 
  this.name = name; 
 } 
}

In addition, we provide another set of interfaces, which respectively mean "can fly", "can run" and "can swim"

interface IFlying { 
 void fly(); 
} 
interface IRunning { 
 void run(); 
} 
interface ISwimming { 
 void swim(); 
}

Next, we create several specific animals

class Cat extends Animal implements IRunning { 
   public Cat(String name) { 
   super(name); 
 } 
   @Override 
   public void run() { 
   System.out.println(this.name + "Running on four legs"); 
 } 
} 
class Fish extends Animal implements ISwimming { 
   public Fish(String name) { 
   super(name); 
 } 
   @Override 
   public void swim() { 
   System.out.println(this.name + "He is swimming with his tail"); 
 } 
} 
class Frog extends Animal implements IRunning, ISwimming { 
   public Frog(String name) { 
   super(name); 
 } 
   @Override 
   public void run() { 
   System.out.println(this.name + "Jumping forward"); 
 } 
   @Override 
   public void swim() { 
   System.out.println(this.name + "He is kicking his legs to swim"); 
 } 
} 

The above code shows the most common usage in Java object-oriented programming: a class inherits a parent class and implements multiple interfaces at the same time

What are the benefits of this design? Always keep the benefits of polymorphism in mind and let the program forget the type. With an interface, the user of a class does not have to focus on the specific type, but only on whether a class has some ability

πŸŽ† Interface usage instance

Sort an array of objects

Given a student class

class Student { 
   private String name; 
   private int score; 
   public Student(String name, int score) { 
   this.name = name; 
   this.score = score; 
 } 
 
   @Override 
   public String toString() { 
   return "[" + this.name + ":" + this.score + "]"; 
 } 
} 

Give a student object array and sort the elements in the object array (in descending order of scores)

Student[] students = new Student[] { 
 new Student("Zhang San", 95), 
 new Student("Li Si", 96), 
 new Student("Wang Wu", 97), 
 new Student("Zhao Liu", 92), 
};

Let our Student class implement the Comparable interface and the compareTo method

class Student implements Comparable{ 
   private String name; 
   private int score; 
   public Student(String name, int score){ 
   this.name = name; 
   this.score = score; 
 } 
   @Override 
public String toString(){ 
   return "[" + this.name + ":" + this.score + "]"; 
 } 
   @Override 
   public int compareTo(Object o){ 
   Student s = (Student)o; 
   if(this.score > s.score){ 
   return -1;
 }else if (this.score < s.score){ 
   return 1; 
 }else{ 
   return 0; 
 } 
 } 
} 

In the sort method, the compareTo method will be called automatically. The parameter of compareTo is Object. In fact, what is passed in is an Object of Student type. Then compare the size relationship between the current Object and the parameter Object (calculated by score)

If the current object should be placed before the parameter object, a number less than 0 is returned;

If the current object should be placed after the parameter object, a number greater than 0 is returned;

Returns 0 if the current object and the parameter object are in no order

// results of enforcement
[[Wang Wu:97], [Li Si:96], [Zhang San:95], [Zhao Liu:92]]

Note: for the sort method, each object of the array to be passed in is "comparable" and needs the ability of compareTo. You can define comparison rules by overriding the compareTo method

In order to further understand the interface, we can try to implement a sort method to complete the sorting process just now (using bubble sorting)

public static void sort(Comparable[] array) { 
 for(int bound = 0; bound < array.length; bound++){ 
    for (int cur = array.length - 1; cur > bound; cur--){ 
 if(array[cur - 1].compareTo(array[cur]) > 0) { 
   // Explain that the order does not meet the requirements, and exchange the position of two variables
    Comparable tmp = array[cur - 1]; 
    array[cur - 1] = array[cur]; 
    array[cur] = tmp; 
   } 
  } 
 } 
} 

Execute the code again

sort(students); 
System.out.println(Arrays.toString(students)); 
// results of enforcement
[[Wang Wu:97], [Li Si:96], [Zhang San:95], [Zhao Liu:92]] 

πŸŽ† summary

Core differences:   Abstract classes can contain ordinary methods and fields. Such ordinary methods and fields can be directly used by subclasses (without rewriting), while interfaces cannot contain ordinary methods. Subclasses must override all abstract methods

Posted by Braimaster on Wed, 17 Nov 2021 16:41:08 -0800