Java Review Notes - Object-Oriented


insert image description here

1. Object-oriented overview

Java is an object-oriented programming language, object-oriented is a programming paradigm, it regards programming as a collection of objects, each object has its own state and behavior, and communicates with each other through message passing interact.

In object-oriented programming, objects are created by defining classes. A class is a template or blueprint that describes the properties and behavior of an object. An object is an instantiation of a class that has the attributes and behaviors defined by the class.

Object-oriented programming has the following core concepts:

  1. Class (Class): A class is an abstraction of an object, describing a class of objects with the same attributes and behaviors. It defines the structure and behavior of objects.

  2. Object (Object): An object is an instantiation of a class, a concrete entity, with properties and behaviors defined by the class.

  3. Attribute: Attribute is the state of an object and describes the characteristics of the object.

  4. Method: A method is the behavior of an object and describes what the object can do.

  5. Encapsulation: Encapsulation is to encapsulate the properties and methods of an object, hide internal implementation details, and only provide the necessary interfaces externally.

  6. Inheritance: Inheritance is a mechanism that allows the creation of a new class derived from an existing class. Subclasses inherit the properties and methods of the parent class, and can add their own unique properties and methods.

  7. Polymorphism (Polymorphism): Polymorphism means that objects of the same class exhibit different behaviors in different situations. Polymorphism is achieved through inheritance and method overriding.

Object-oriented programming has the characteristics of encapsulation, inheritance, and polymorphism, which can improve code reusability, maintainability, and scalability. It makes the program design more modular, easier to understand and modify. Object-oriented programming is widely used in Java and is one of the fundamental features of the Java language.

Second, classes and objects

(1) Overview of classes and objects

In Java, a class is the basic unit of object-oriented programming. It is an abstract description of an object and defines its properties and behavior. An object is an instantiation of a class, a concrete entity that has the properties and behaviors defined by the class.

A class definition usually consists of the following parts:

  1. Class declaration: classA class is declared using the keyword followed by the name of the class.

  2. Attribute (member variable): The attribute of a class is a variable that describes the characteristics of an object, which can be a basic data type or an object of another class. Attributes are defined inside the class, and access permissions can be controlled through access modifiers.

  3. Methods: Methods of a class are functions that describe the behavior of an object, defining what the object can do. Methods are also defined inside the class, and access permissions can be controlled through access modifiers.

  4. Construction method: A construction method is a special method used to initialize an object when it is created. The constructor has the same name as the class, has no return type, and can be overloaded.

  5. Access modifiers: Access modifiers are used to control access to classes, properties, and methods, including public, protected, private, and default (do not declare access modifiers).

  6. Class relationship: There may be inheritance relationships, implementation relationships, and association relationships between classes. These relationships can be represented by keywords and reference type variables extends.implements

An object is an instantiation of a class by using newkeywords to create an object of the class. After the object is created, you can use the object's reference variable to access the object's properties and call the object's methods.

For example, here is an example of a simple Java class and object:

// 定义一个类
class Person {
    
    
    // 属性
    String name;
    int age;

    // 构造方法
    public Person(String name, int age) {
    
    
        this.name = name;
        this.age = age;
    }

    // 方法
    public void sayHello() {
    
    
        System.out.println("Hello, my name is " + name + ", I'm " + age + " years old.");
    }
}

// 创建对象并使用
public class Main {
    
    
    public static void main(String[] args) {
    
    
        // 创建Person对象
        Person person = new Person("John", 25);

        // 访问对象的属性
        System.out.println(person.name); // 输出:John
        System.out.println(person.age);  // 输出:25

        // 调用对象的方法
        person.sayHello(); // 输出:Hello, my name is John, I'm 25 years old.
    }
}

In the above example, we defined a Person class with two properties (name and age) and one method (sayHello). Then in the main function, we create a Person object, and access the properties of the object and call the method of the object through the reference variable of the object.

(2) Supplementary considerations for defining classes

When defining a class in Java, in addition to following the standard JavaBean specification, there are some additional considerations:

  1. Naming conventions for class names: class names should be named in camel case, with the first letter capitalized, for example "Person".
  2. File name naming convention: The file name of the Java source file should be the same as the class name, with the extension .java, for example "Person.java".
  3. Package naming convention: If the class is in a package, the package name should be all lowercase and use a dot (.) as a separator, such as "com.example". The package name should reflect the class hierarchy and uniqueness of the project it belongs to.
  4. Use of access modifiers: Classes can use four different access modifiers: public, protected, default (that is, do not write any modifiers), and private. Select the appropriate access modifiers as needed to control the visibility and access of the class.
  5. Inheritance and Interface Implementation: Classes in Java can inherit from other classes and implement one or more interfaces. Inheritance and interface implementation are achieved through the keywords extends and implements.
  6. Naming conventions for member variables and local variables: member variables should be named in camel case, with the first letter lowercase, such as "age". Local variables should use camelCase or a short name such as "i".
  7. Class design principles: When defining classes, you can consider some design principles, such as the single responsibility principle, the open and closed principle, and the dependency inversion principle, to improve code maintainability, scalability, and reusability.

When writing Java code, following these considerations can make the code more regular, readable, and maintainable. At the same time, it can also improve the portability of the code and keep it consistent with other developers' code.

Three, encapsulation

In Java, encapsulation is an important concept of object-oriented programming. It encapsulates the properties and methods of a class, hides the internal implementation details of the class from external users, and only exposes the necessary interfaces for external access.

The purpose of encapsulation is to protect the internal data of the class from being directly accessed and modified, and can only be operated through the public methods provided by the class. This prevents erroneous modification and accidental access to internal data by external code, improving code security and maintainability.

In Java, encapsulation is achieved through access modifiers:

  1. private: Private access modifier, which can only be accessed in the current class, and cannot be directly accessed by external classes.

  2. public: public access modifier, can be accessed anywhere.

  3. protected: A protected access modifier that can be accessed in the current class, classes in the same package, and subclasses.

  4. Default (no access modifier declared): The default access modifier can only be accessed within the current package.

Normally, the properties of a class should be declared as private (private) access modifiers, and then access and modify the value of the property through public (public) setter and getter methods. In this way, additional logical operations can be added to the setter and getter methods to realize the control and protection of properties.

Here is a sample code:

class Person {
    
    
    private String name;
    private int age;

    public String getName() {
    
    
        return name;
    }

    public void setName(String name) {
    
    
        // 可以在setter方法中添加逻辑判断
        if (name != null && !name.isEmpty()) {
    
    
            this.name = name;
        }
    }

    public int getAge() {
    
    
        return age;
    }

    public void setAge(int age) {
    
    
        // 可以在setter方法中添加逻辑判断
        if (age >= 0 && age <= 100) {
    
    
            this.age = age;
        }
    }
}

public class Main {
    
    
    public static void main(String[] args) {
    
    
        Person person = new Person();
        person.setName("John");
        person.setAge(25);

        System.out.println(person.getName()); // 输出:John
        System.out.println(person.getAge());  // 输出:25
    }
}

In the above example, the attributes name and age of the Person class are both declared as private (private) access modifiers, which cannot be directly accessed externally. The value of the property is accessed and modified through the public setter and getter methods, and logical judgment is added to the setter method to ensure the validity of the property value.

The advantage of this is that the internal implementation details of the Person class are hidden from the outside, and the outside can only operate attributes through the public interface, which improves the security and maintainability of the code. At the same time, if you need to perform additional processing on the access and modification of attributes, you only need to add corresponding logic in the setter and getter methods.

Fourth, the principle of proximity and the this keyword

(1) Proximity principle

In Java, the Lexical Scoping principle means that the scope of a variable in a program is determined by where it is declared in the code. When there are variables with the same name in the program, the proximity principle stipulates that within a given scope, the most recently declared variable is used first.

For example, consider the following sample code:

public class Main {
    
    
    public static void main(String[] args) {
    
    
        int x = 5;
        
        {
    
    
            int x = 10;
            System.out.println(x);  // 输出:10
        }
        
        System.out.println(x);  // 输出:5
    }
}

In the above code, there are two variables x with the same name. The first x is declared in the main method and the second x is declared inside a code block. According to the principle of proximity, when we access variable x inside a code block, the most recently declared variable should be used, i.e. x = 10. And when we access the variable x outside the code block, the variable declared in the nearest scope should be used, i.e. x = 5.

The principle of proximity is very important in Java. It ensures that the scope of variables is controllable and avoids naming conflicts and variable confusion. When writing code, we should develop good naming habits and avoid using the same variable name to avoid misunderstandings and mistakes. At the same time, reasonable use of code blocks and methods can control the scope of variables, follow the principle of proximity, and make the code clearer and easier to understand.

(2) this keyword

In Java, this is a keyword that represents a reference to the current object. The this keyword can be used in member methods of a class to refer to member variables and member methods of the current object.

Using the this keyword can solve the following two common problems:

  1. Resolving naming conflicts: When a member variable has the same name as a method parameter or a local variable, use the this keyword to clearly specify whether the member variable or the method parameter or local variable is to be referenced. For example:
public class Person {
    
    
    private String name;
    
    public void setName(String name) {
    
    
        this.name = name;
    }
}

// 使用示例
Person person = new Person();
person.setName("John");

In the above example, the parameter name of the setName method is name, and the member variable is also name. To resolve naming conflicts, we use the this keyword to refer to member variables, ie this.name = name.

  1. Call other construction methods in the construction method: In a class, multiple construction methods (overloading) can be defined. When we call other construction methods in a construction method, we can use the this keyword. For example:
public class Person {
    
    
    private String name;
    private int age;
    
    public Person(String name) {
    
    
        this.name = name;
    }
    
    public Person(String name, int age) {
    
    
        this(name);  // 调用另一个构造方法
        this.age = age;
    }
}

// 使用示例
Person person = new Person("John", 25);

In the above example, the second construction method calls the first construction method, and uses this(name) to pass the name parameter, which can avoid code duplication.

In short, the this keyword is used in Java to refer to the member variables and member methods of the current object, and other construction methods can be called in the construction method. Its use can help resolve issues of naming conflicts and code duplication.

Five, construction method

(1) Overview of the construction method

A constructor is a special method used to create an object and initialize its properties. In Java, each class can have one or more constructors.

An overview of the construction method is as follows:

  1. The name of the constructor must be exactly the same as the class name and have no return type (including void).
  2. The construction method can have zero or more parameters, which are used to receive the value passed in from the outside.
  3. Constructors can be overloaded, that is, a class can have multiple constructors as long as their parameter lists are different.
  4. If the class does not explicitly define a constructor, the system will automatically provide a default no-argument constructor. However, if a constructor with parameters is defined in the class, the system will not automatically provide a default constructor and needs to be defined manually.
  5. Constructors can have access modifiers such as public, protected, private, or default (i.e. no modifiers). Depending on your needs, you can choose appropriate access modifiers to control access to the constructor.
  6. Constructors are usually used to initialize properties when creating an object. In the construction method, you can use the parameters passed in to assign values ​​to the properties of the object.
  7. The constructor is called when the object is created using the new keyword, creating the object and allocating memory space. The constructor is executed immediately after the object is created.
  8. The constructor cannot be called through the object, only through the new keyword.
  9. A constructor can use the this keyword to call other constructors in the same class, which is called a chain of constructors. Through the construction method chain, different construction methods can be used to initialize properties when creating objects.

The main function of the constructor method is to initialize the properties of the object and provide different ways to create the object. Reasonable use of construction methods can ensure that the properties of the object are initialized correctly and meet the needs of different scenarios.

(2) The role of the construction method

The Java constructor is a special method that is used to create an object and initialize its properties. It must have the same name as the class and have no return type (including void). The construction method is automatically called when the new keyword is used to allocate space for the object in memory and initialize the properties of the object.

The functions of the construction method include:

  1. Create Object: The constructor method is used to create an instance of an object in memory. When using the new keyword to create an object, the system will automatically call the constructor of the corresponding class, and allocate the memory space required by the object through the constructor.

  2. Initialize object properties: The constructor can initialize the properties of the object and assign initial values ​​to the properties of the object. By setting parameters in the constructor, you can pass initial values ​​for properties when creating objects.

  3. Provide a default constructor: If the class does not explicitly define a constructor, the system will automatically provide a default no-argument constructor. The default constructor can be called when creating an object. If there is a custom constructor in the class, but no parameterless constructor is provided, the compiler will report an error if no parameters are passed when creating the object.

  4. Initialize the state of the object: the constructor can initialize the state of the object when creating the object, such as setting the initial state of the object, connecting to the database, and other operations.

  5. Control the object creation process: By overloading the construction method and using access modifiers, you can control the object creation process, limit the access rights of the object, and so on.

In summary, the construction method plays a vital role in creating an object. It is not only used to allocate the memory space of the object, but also to initialize the properties of the object, provide a default construction method, initialize the state of the object, and control the object of the creation process. The construction method plays an important role in the definition of the class and is a basic concept in object-oriented programming.

(2) Types of construction methods and their respective functions

In Java, constructors can be divided into the following types:

  1. Default constructor (no-argument constructor): If the class does not explicitly define a constructor, the system will automatically provide a default no-argument constructor. The default constructor takes no parameters and does nothing. Its function is to create an object and allocate memory space, but does not initialize the properties of the object.

  2. Constructor with parameters: A constructor with parameters can accept one or more parameters, which are used to pass the initial value when creating the object. By setting parameters in the constructor, the properties of the object can be initialized. The construction method with parameters can be overloaded according to different parameter combinations to meet different needs.

  3. Overloaded constructor: In a class, multiple constructors can be defined as long as their parameter lists are different. The role of the overloaded constructor is to provide multiple ways to create objects, and initialize the properties of the object according to different parameter combinations.

  4. Private construction method: A private construction method refers to a construction method whose access modifier is private. It is only visible in this class and cannot be directly accessed externally. The role of the private constructor is to restrict the creation of objects, usually used to implement singleton patterns or tool classes, to ensure that objects can only be created in a specific way.

  5. Construction method chain: In a construction method, you can use the this keyword to call other construction methods in the same class, which is called a construction method chain. The function of the construction method chain is to initialize properties through different construction methods when creating objects, avoiding code duplication.

In summary, the types of constructors include default constructors, constructors with parameters, overloaded constructors, private constructors, and constructor chains. Their functions are to create objects and allocate memory space, initialize object properties, provide multiple ways to create objects, limit object creation, and call other construction methods in construction methods to avoid code duplication. Different construction methods can be used flexibly according to requirements.

(3) Notes on the construction method

When using the constructor method, you need to pay attention to the following points:

  1. The constructor is the same as the class name: The name of the constructor must be exactly the same as the class name, and there is no return type (including void). If the name of the constructor does not match the name of the class, it will be treated as a normal method, not a constructor.

  2. Overloading of constructors: A class can have multiple constructors as long as their parameter lists are different. The overloading of the constructor can provide multiple ways to create objects, and initialize them according to different parameter combinations.

  3. Provision of default constructor: If the class does not explicitly define a constructor, the system will automatically provide a default no-argument constructor. However, if a constructor with parameters is defined in the class, the system will not automatically provide a default constructor and needs to be defined manually.

  4. Access modifiers for constructors: Constructors can use public, protected, private, or default (ie, no modifiers) access modifiers. Depending on your needs, you can choose appropriate access modifiers to control access to the constructor.

  5. Construction method call: By using the new keyword to call the construction method, create an object and allocate memory space. The constructor can initialize properties when the object is created, but it cannot be called again after the object is created.

  6. Chain call of construction methods: In a construction method, you can use this keyword to call other construction methods in the same class, which is called a construction method chain. Through the construction method chain, different construction methods can be used to initialize properties when creating objects.

  7. The use of private constructors: The access rights of private constructors are limited to the inside of the class, and cannot be accessed directly from the outside. Private constructors are often used to implement singleton patterns or utility classes, limiting object creation.

  8. The construction method cannot be inherited: the construction method will not be inherited, and the subclass cannot directly call the construction method of the parent class. The super keyword can be used in the subclass to call the constructor of the parent class to initialize the properties inherited from the parent class.

The above are some points to pay attention to when using the constructor method. Reasonable use of construction methods can correctly initialize the properties of the object and control the creation and access rights of the object.

Six, the standard JavaBean class

In Java, a standard JavaBean class is a class that follows a specific specification for encapsulating data and providing methods for accessing and manipulating these data. JavaBean classes are usually used to pass data between different layers, such as storing and passing form data in web development.

A standard JavaBean class should meet the following requirements:

  1. The class must have a public no-argument constructor: this allows JavaBean objects to be instantiated using the default constructor.
  2. Attributes must be private: JavaBean classes typically declare attributes as private and provide access to the attributes through public getter and setter methods.
  3. Provide public getter and setter methods: The JavaBean class should provide public getter and setter methods for each property to allow other classes to access and modify the value of the property.
  4. Implement the Serializable interface (optional): If the JavaBean class needs to be serialized or needs to be transmitted on the network, the Serializable interface can be implemented.

The following is an example of a standard JavaBean class:

public class Person implements Serializable {
    
    
    private String name;
    private int age;
    
    public Person() {
    
    
        // 默认的无参构造方法
    }
    
    public String getName() {
    
    
        return name;
    }
    
    public void setName(String name) {
    
    
        this.name = name;
    }
    
    public int getAge() {
    
    
        return age;
    }
    
    public void setAge(int age) {
    
    
        this.age = age;
    }
}

In the above example, the Person class is a standard JavaBean class. It meets the following requirements: have a public no-argument constructor, private properties, public getter and setter methods, and optionally implement the Serializable interface.

Standard JavaBean classes can be used for various purposes, such as data transfer objects (DTO) in the Spring framework, and persistent entity classes in Hibernate. By following the JavaBean specification, data can be better encapsulated and managed, and access and manipulation of data can be provided.

Seven, the object memory map of the three situations

(1) Memory map of an object

Here is an example memory map of a Java object:

+---------------------------+
|                           |
|       Object Header       |
|                           |
+---------------------------+
|     Instance Variables    |
|                           |
+---------------------------+
|                           |
|       Padding             |
|                           |
+---------------------------+

The memory map of Java objects mainly includes the following parts:

  1. Object Header: The object header contains some metadata related to the object, such as the object's hash code, lock status, GC mark and other information.
  2. Instance Variables: Instance variables store the attribute values ​​​​of objects. Each instance variable occupies a certain amount of memory space.
  3. Padding: Memory alignment padding, used to maintain object alignment and performance optimization.

In memory, Java objects are allocated in the heap (Heap). When an object is created using the new keyword, a contiguous memory space is allocated in the heap to store the instance variables of the object. Object headers and memory alignment padding do not count towards the object's instance variable space.

Instance variables can be basic data types (such as int, double, etc.) or reference types (such as String, array, etc.). For instance variables of reference types, what is actually stored is a reference to the object, not the object itself.

By assigning values ​​to the instance variables of the object, you can modify the property values ​​of the object. Different objects have independent memory spaces, so their properties can be modified and accessed independently.

In Java, the memory management of objects is the responsibility of the garbage collector (Garbage Collector). When the object is no longer referenced, the garbage collector will automatically reclaim the memory space occupied by the object for subsequent object allocation.

(2) Memory map of multiple objects

Here is an example of a memory map of multiple objects in a Java program:

+------------------------------+
|        Object Header         |
+------------------------------+
|      Instance Variables      |
+------------------------------+
|        Padding               |
+------------------------------+

+------------------------------+
|        Object Header         |
+------------------------------+
|      Instance Variables      |
+------------------------------+
|        Padding               |
+------------------------------+

...

Each Java object has its own memory map, and objects are stored independently of each other and have the same structure. Each object's memory map includes the object header, instance variables, and memory alignment padding.

In memory, each object is allocated in a different memory space in the heap (Heap). When creating multiple objects, Java allocates multiple contiguous blocks of memory in the heap to store the instance variables of each object. The instance variables of each object can be modified and accessed independently.

There can be shared instance variables between the memory maps of different objects, that is, the same instance variable of multiple objects points to the same memory location. This usually happens with instance variables of reference types, when multiple objects refer to the same object and their instance variables point to references to the same object.

The Garbage Collector in Java automatically reclaims the memory space occupied by objects that are no longer referenced. When objects are no longer referenced, the garbage collector marks them as garbage and reclaims the memory they occupy when appropriate for subsequent object allocations.

In summary, the memory maps of multiple objects are allocated independently in the heap, and each object has its own object header, instance variables, and memory alignment padding. Objects can share instance variables of reference type, and the garbage collector will be responsible for reclaiming objects that are no longer referenced.

(3) Two variables point to the memory map of the same object

Here is an example of a memory map in a Java program where two variables point to the same object:

+------------------------+
|      Variable 1        |
+------------------------+
|     Memory Address     |
+------------------------+

      |
      v

+------------------------+
|      Variable 2        |
+------------------------+
|     Memory Address     |
+------------------------+

      |
      v

+------------------------------+
|        Object Header         |
+------------------------------+
|      Instance Variables      |
+------------------------------+
|        Padding               |
+------------------------------+

In the above example, Variable 1and Variable 2are two Java variables that both store the memory address of the same object. This means that both variables actually point to the same object.

In the heap, an object is allocated memory space, which has an object header and instance variables. Variable 1and Variable 2stores the address of the object in memory, through which they can share access to the instance variables of the object.

Modifying the state of the object pointed to by one variable will affect the state of the object accessed through another variable. This is because the two variables point to the same object, and they share the memory space of the same object.

In Java, an object reference is a value that points to the memory address of the object, not the object itself. This allows multiple variables to refer to the same object, allowing objects to be shared and interacted with. The garbage collector will be responsible for reclaiming the memory space occupied by objects that are no longer referenced, but only when all variables that refer to the object no longer refer to it, the object will be considered garbage that is no longer referenced.

Eight, basic data types and reference data types

(1) Basic data types

Java basic data types refer to the basic data types in the Java language, which are predefined and not defined by classes. Java's basic data types include the following:

  1. byte: Represents an 8-bit signed integer ranging from -128 to 127.
  2. short: Represents a 16-bit signed integer ranging from -32,768 to 32,767.
  3. int: Represents a 32-bit signed integer ranging from -2 31 to 2 31-1.
  4. long: Represents a 64-bit signed integer ranging from -2 63 to 2 63-1.
  5. float: Indicates a 32-bit single-precision floating-point number with a range of plus or minus 3.40282347e+38F (effective digits are 6-7 digits).
  6. double: indicates a 64-bit double-precision floating-point number with a range of plus or minus 1.79769313486231570e+308 (effective digits are 15 digits).
  7. boolean: Boolean value, only two values: true and false.
  8. char: Indicates 16-bit Unicode characters.

Primitive data types occupy a fixed size in memory, and they are stored directly on the stack, not on the heap (unlike reference types). Each basic data type has a corresponding wrapper class, which is used to provide operations and methods related to the data type.

The main advantage of primitive data types is that they are efficient and take up less memory space. However, they cannot call methods directly because they are not objects, so wrapper classes are needed to handle some special needs of basic data types, such as comparisons, conversions, etc.

(2) Reference data type

Java reference data types refer to non-basic data types (also known as object types) in the Java language, which are created by classes or interfaces. Java's reference data types include the following:

  1. Class: The most common form of reference data type is a class. A class is a custom data type that can contain attributes (member variables) and methods (member methods), and objects of this class can be created.
  2. Interface: An interface is a reference data type that defines a set of method signatures that can be implemented by a class so that the class has the behavior defined in the interface.
  3. Array (Array): An array is a container used to store data of the same type, and can store elements of basic data types or reference data types.
  4. Enumeration (Enum): Enumeration is a special reference data type, which restricts variables to only take specific values, which are predefined in the enumeration type.
  5. String (String): A string is a reference data type that represents a sequence of characters. In Java, strings are immutable, i.e. once created, they cannot be modified.

Objects of reference data types are stored in heap memory, while references (variables) themselves are stored in stack memory. Unlike basic data types, variables of reference data types can call methods, and can manipulate the properties and behavior of objects by reference. When an object is not referenced by any reference variable, it becomes garbage and the memory is automatically reclaimed by Java's garbage collection mechanism.

Nine, the memory principle of this

In Java, the keyword "this" represents a reference to the current object. It can be used in object methods to access member variables and member methods of the current object.

In terms of memory principles, whenever we create an object, Java will allocate a memory space for the object in the heap memory, and store the member variables of the object in this memory space. At the same time, Java will create a reference to the memory space for this object.

When we use the "this" keyword in an object's method, the compiler will resolve the "this" keyword as a reference to the current object. Specifically, the compiler will pass the "this" keyword to the method as a method parameter, so that the method can access the member variables and member methods of the current object.

In memory, each thread will have a stack, called "thread stack". When a method is called, Java will create a "stack frame" in the stack of the current thread. The stack frame contains information such as local variables of the method, method parameters, and method return values. At this time, the "this" keyword is stored in a special location in the stack frame, which is used to point to the memory space of the current object.

To sum up, the "this" keyword in Java is a reference to the current object, which is used in the object's methods. Its memory principle is to store a reference to the current object in the stack frame of the current thread, so that the method can access the member variables and member methods of the current object.

Ten, member variables and local variables

(1) Member variables

Member variables in Java, also known as instance variables, are variables defined in a class. They belong to objects, and each object has its own copy of member variables used to store the state and properties of the object.

Member variables have the following characteristics:

  1. Scope: The scope of member variables is the entire class, which can be accessed in any method, construction method, or code block of the class.
  2. Life cycle: The life cycle of the member variable is consistent with the life cycle of the object. When the object is created, the member variable allocates the corresponding memory space; when the object is destroyed, the memory space of the member variable is also released.
  3. Default value: If no value is explicitly assigned, the member variable will have a default value. For example, the default value of an integer member variable is 0, and the default value of a Boolean member variable is false.
  4. Accessibility: Member variables can be restricted using access modifiers, such as public, private, protected, etc. Depending on the access modifiers, member variables can be accessed by different classes and methods.

Member variables are usually used to store properties and state information of objects, and can be used and modified in various methods of the class. They are declared in the class, but they are not initialized and assigned in the method, but are assigned initial values ​​​​with the initialization of the object when the object is created.

(2) Local variables

A local variable in Java is a variable declared within a method, constructor, or code block. They are only visible within the declared method, constructor or code block and only exist during the execution of the method, constructor or code block.

Local variables have the following characteristics:

  1. Scope: The scope of a local variable is limited to the method, constructor, or code block in which it is declared. Beyond that scope, local variables are no longer visible.
  2. Life cycle: The life cycle of a local variable is consistent with the execution cycle of a method, constructor, or code block. After the execution of the method, constructor or code block, the memory space of the local variables will be freed.
  3. Must be explicitly initialized: Local variables must be explicitly initialized before they can be used. Otherwise, the compiler will report an error.
  4. Does not have a default value: Unlike member variables, local variables do not have a default value. Must be assigned a value before use.

Local variables are often used to temporarily store and manipulate data within methods, constructors, or code blocks. They are declared inside a method, constructor, or code block and are only valid within the declared method, constructor, or code block. Once execution leaves the method, constructor, or code block, the memory space for local variables is freed.

(3) The difference between member variables and local variables

Member variables and local variables in Java are two different types of variables that differ in terms of scope, lifetime, and accessibility.

  1. scope:

    • Member variables (also known as instance variables) are variables defined inside a class, outside of methods. Its scope is the entire class and can be accessed by all methods in the class.
    • Local variables are variables defined in methods, constructors, and code blocks. Its scope is only in the declared method and can only be accessed inside the method.
  2. life cycle:

    • The life cycle of member variables is consistent with the life cycle of objects. When the object is created, the member variable allocates the corresponding memory space; when the object is destroyed, the memory space of the member variable is also released.
    • The lifetime of a local variable begins when the method executes and ends when the method executes. When the method finishes executing, the memory space for local variables is also released.
  3. Initialization value:

    • Member variables can have default values, and if not explicitly assigned, they vary according to the data type. For example, the default value of an integer member variable is 0, and the default value of a Boolean member variable is false.
    • Local variables have no default value and must be explicitly assigned before use, otherwise a compilation error will occur.
  4. Accessibility:

    • Member variables can be restricted using access modifiers such as public, private, protected, etc. Depending on the access modifiers, member variables can be accessed by different classes and methods.
    • Local variables do not have access modifiers, they can only be accessed inside the method in which they are declared.

To sum up, member variables are variables defined in the class and outside the method, the scope is the entire class, and the life cycle is consistent with the object; while local variables are variables defined in methods, constructors and code blocks, and the scope is only in Inside the declared method, the life cycle is during the execution of the method.

Eleven, comprehensive exercises

(1) Text Version Fighting Game

Requirements: In fighting games, the name and blood volume of each game character are different. When selecting a character (when new object), this information should be determined.

The following is an object-oriented Java code example to implement a text version of a fighting game with names and health:

import java.util.Random;
import java.util.Scanner;

public class FightGame {
    
    
    private static final int MAX_HEALTH = 100;
    private static final int MAX_ATTACK_DAMAGE = 20;
    
    public static void main(String[] args) {
    
    
        Scanner scanner = new Scanner(System.in);
        Random random = new Random();
        
        System.out.println("欢迎来到文字版格斗游戏!");
        
        System.out.print("请输入你的角色名字:");
        String playerName = scanner.nextLine();
        System.out.print("请输入你的角色生命值(1-" + MAX_HEALTH + "):");
        int playerHealth = scanner.nextInt();
        
        Player player = new Player(playerName, playerHealth);
        Enemy enemy = new Enemy("敌人", MAX_HEALTH);
        
        System.out.println("你的角色名字是:" + player.getName());
        System.out.println("你的初始生命值为:" + player.getHealth());
        System.out.println("敌人的生命值为:" + enemy.getHealth());
        System.out.println("游戏开始!");
        
        while (player.getHealth() > 0 && enemy.getHealth() > 0) {
    
    
            System.out.print("请输入你的攻击力(1-" + MAX_ATTACK_DAMAGE + "):");
            int playerAttack = scanner.nextInt();
            
            int enemyAttack = random.nextInt(MAX_ATTACK_DAMAGE) + 1;
            
            enemy.takeDamage(playerAttack);
            player.takeDamage(enemyAttack);
            
            System.out.println("你对敌人造成了" + playerAttack + "点伤害!");
            System.out.println("敌人对你造成了" + enemyAttack + "点伤害!");
            System.out.println("你的剩余生命值为:" + player.getHealth());
            System.out.println("敌人的剩余生命值为:" + enemy.getHealth());
        }
        
        if (player.getHealth() <= 0) {
    
    
            System.out.println("你输了游戏!");
        } else {
    
    
            System.out.println("你赢了游戏!");
        }
        
        System.out.println("游戏结束!");
    }
}

class Character {
    
    
    private String name;
    private int health;
    
    public Character(String name, int health) {
    
    
        this.name = name;
        this.health = health;
    }
    
    public void takeDamage(int damage) {
    
    
        health -= damage;
        if (health < 0) {
    
    
            health = 0;
        }
    }
    
    public String getName() {
    
    
        return name;
    }
    
    public int getHealth() {
    
    
        return health;
    }
}

class Player extends Character {
    
    
    public Player(String name, int health) {
    
    
        super(name, health);
    }
}

class Enemy extends Character {
    
    
    public Enemy(String name, int health) {
    
    
        super(name, health);
    }
}

In this example, we create a Character class as the base class of the character, which contains two attributes of name and blood volume, as well as the injury method. The Player class and the Enemy class inherit from the Character class, representing the player and enemy characters respectively. When instantiating the Player and Enemy objects, you need to pass in the name and HP parameters to initialize the objects.

In the main method, we first create the Player object and the Enemy object according to the name and blood volume entered by the player. Then, get and modify the character's attributes by calling the object's methods. During the game, the player and the enemy take turns to attack, and the character's HP is updated according to the damage caused by the attack. Finally, judge the outcome of the game based on the blood volume of the player and the enemy, and output the corresponding results.

(2) Object array exercises

1, object array 1

Requirement: Define an array to store 3 commodity objects.
Product attributes: product id, name, price, inventory.
Create three product objects and store the product objects into an array.

The following is an example of using object-oriented Java code to create product objects and store them in an object array:

import java.util.Scanner;

public class ProductArray {
    
    
    public static void main(String[] args) {
    
    
        Scanner scanner = new Scanner(System.in);
        
        Product[] products = new Product[3];
        
        for (int i = 0; i < products.length; i++) {
    
    
            System.out.println("请输入第" + (i + 1) + "个商品的信息:");
            System.out.print("商品ID:");
            int id = scanner.nextInt();
            System.out.print("商品名称:");
            String name = scanner.next();
            System.out.print("商品价格:");
            double price = scanner.nextDouble();
            System.out.print("商品库存:");
            int stock = scanner.nextInt();
            
            Product product = new Product(id, name, price, stock);
            
            products[i] = product;
        }
        
        System.out.println("三个商品的信息如下:");
        for (int i = 0; i < products.length; i++) {
    
    
            System.out.println("商品ID:" + products[i].getId());
            System.out.println("商品名称:" + products[i].getName());
            System.out.println("商品价格:" + products[i].getPrice());
            System.out.println("商品库存:" + products[i].getStock());
            System.out.println("---------------------------");
        }
    }
}

class Product {
    
    
    private int id;
    private String name;
    private double price;
    private int stock;
    
    public Product(int id, String name, double price, int stock) {
    
    
        this.id = id;
        this.name = name;
        this.price = price;
        this.stock = stock;
    }
    
    public int getId() {
    
    
        return id;
    }
    
    public String getName() {
    
    
        return name;
    }
    
    public double getPrice() {
    
    
        return price;
    }
    
    public int getStock() {
    
    
        return stock;
    }
}

In this example, we created a Product class to represent the product, including four attributes of the product ID, name, price and inventory. In the main method of the ProductArray class, we first define a Product array with a length of 3 to store product objects.

Then, get the information of each product from the user input through a loop, and use the constructor to create the Product object. Store each created Product object into an array.

Finally, by traversing the array, print out the attributes of each product object and show it to the user.

2, object array 2

Requirement: Define an array to store 3 car objects.
Attributes of the car: brand, price, color.
Create three car objects, enter the data through the keyboard, and store the data in the array.

The following is an example of using object-oriented Java code to create a car object and store it in an object array:

import java.util.Scanner;

public class CarArray {
    
    
    public static void main(String[] args) {
    
    
        Scanner scanner = new Scanner(System.in);
        
        Car[] cars = new Car[3];
        
        for (int i = 0; i < cars.length; i++) {
    
    
            System.out.println("请输入第" + (i + 1) + "部汽车的信息:");
            System.out.print("汽车品牌:");
            String brand = scanner.next();
            System.out.print("汽车价格:");
            double price = scanner.nextDouble();
            System.out.print("汽车颜色:");
            String color = scanner.next();
            
            Car car = new Car(brand, price, color);
            
            cars[i] = car;
        }
        
        System.out.println("三部汽车的信息如下:");
        for (int i = 0; i < cars.length; i++) {
    
    
            System.out.println("汽车品牌:" + cars[i].getBrand());
            System.out.println("汽车价格:" + cars[i].getPrice());
            System.out.println("汽车颜色:" + cars[i].getColor());
            System.out.println("---------------------------");
        }
    }
}

class Car {
    
    
    private String brand;
    private double price;
    private String color;
    
    public Car(String brand, double price, String color) {
    
    
        this.brand = brand;
        this.price = price;
        this.color = color;
    }
    
    public String getBrand() {
    
    
        return brand;
    }
    
    public double getPrice() {
    
    
        return price;
    }
    
    public String getColor() {
    
    
        return color;
    }
}

In this example, we create a Car class to represent a car, including three attributes of the car's brand, price and color. In the main method of the CarArray class, we first define a Car array with a length of 3 for storing car objects.

Then, get the information of each car from the user input through a loop, and use the constructor to create the Car object. Store each created Car object into an array.

Finally, by traversing the array, print out the properties of each car object and show it to the user.

3, object array 3

Requirement: Define an array to store 3 mobile phone objects.
Attributes of the mobile phone: brand, price, color.
Requirement: Calculate the average price of three mobile phones.

The following is an object-oriented Java code example to create a mobile phone object and calculate the average price:

import java.util.Scanner;

public class PhoneArray {
    
    
    public static void main(String[] args) {
    
    
        Scanner scanner = new Scanner(System.in);
        
        Phone[] phones = new Phone[3];
        
        for (int i = 0; i < phones.length; i++) {
    
    
            System.out.println("请输入第" + (i + 1) + "部手机的信息:");
            System.out.print("手机品牌:");
            String brand = scanner.next();
            System.out.print("手机价格:");
            double price = scanner.nextDouble();
            System.out.print("手机颜色:");
            String color = scanner.next();
            
            Phone phone = new Phone(brand, price, color);
            
            phones[i] = phone;
        }
        
        double total = 0;
        for (int i = 0; i < phones.length; i++) {
    
    
            total += phones[i].getPrice();
        }
        
        double average = total / phones.length;
        
        System.out.println("三部手机的平均价格为:" + average);
    }
}

class Phone {
    
    
    private String brand;
    private double price;
    private String color;
    
    public Phone(String brand, double price, String color) {
    
    
        this.brand = brand;
        this.price = price;
        this.color = color;
    }
    
    public String getBrand() {
    
    
        return brand;
    }
    
    public double getPrice() {
    
    
        return price;
    }
    
    public String getColor() {
    
    
        return color;
    }
}

In this example, we create a Phone class to represent a mobile phone, including three attributes of the mobile phone's brand, price and color. In the main method of the PhoneArray class, we first define a Phone array with a length of 3 to store phone objects.

Then, obtain the information of each mobile phone from the user input through a loop, and use the constructor to create a Phone object. Store each created Phone object into an array.

Next, we use a variable total to add up the prices of all phones. Then, calculate the average price by dividing by the length of the array.

Finally, we print out the calculated average price and show it to the user.

4. Define array 4

Requirement: Define an array to store 4 girlfriend objects.
Attributes of girlfriend: name, age, gender, hobbies.
Requirement 1: Calculate the average age of the four girlfriends.
Requirement 2: How many girlfriends are there whose statistical age is lower than the average? And print out all their information.

The following is an object-oriented Java code example to create a girlfriend object and calculate the average age, and count the number of girlfriends whose age is lower than the average and print their information:

import java.util.Scanner;

public class GirlfriendArray {
    
    
    public static void main(String[] args) {
    
    
        Scanner scanner = new Scanner(System.in);
        
        Girlfriend[] girlfriends = new Girlfriend[4];
        
        for (int i = 0; i < girlfriends.length; i++) {
    
    
            System.out.println("请输入第" + (i + 1) + "个女朋友的信息:");
            System.out.print("姓名:");
            String name = scanner.next();
            System.out.print("年龄:");
            int age = scanner.nextInt();
            System.out.print("性别:");
            String gender = scanner.next();
            System.out.print("爱好:");
            String hobby = scanner.next();
            
            Girlfriend girlfriend = new Girlfriend(name, age, gender, hobby);
            
            girlfriends[i] = girlfriend;
        }
        
        int totalAge = 0;
        for (int i = 0; i < girlfriends.length; i++) {
    
    
            totalAge += girlfriends[i].getAge();
        }
        
        int averageAge = totalAge / girlfriends.length;
        
        System.out.println("四个女朋友的平均年龄为:" + averageAge);
        
        int count = 0;
        System.out.println("年龄低于平均值的女朋友有:");
        for (int i = 0; i < girlfriends.length; i++) {
    
    
            if (girlfriends[i].getAge() < averageAge) {
    
    
                count++;
                System.out.println(girlfriends[i].toString());
            }
        }
        
        System.out.println("共有" + count + "个女朋友的年龄低于平均值。");
    }
}

class Girlfriend {
    
    
    private String name;
    private int age;
    private String gender;
    private String hobby;
    
    public Girlfriend(String name, int age, String gender, String hobby) {
    
    
        this.name = name;
        this.age = age;
        this.gender = gender;
        this.hobby = hobby;
    }
    
    public String getName() {
    
    
        return name;
    }
    
    public int getAge() {
    
    
        return age;
    }
    
    public String getGender() {
    
    
        return gender;
    }
    
    public String getHobby() {
    
    
        return hobby;
    }
    
    @Override
    public String toString() {
    
    
        return "姓名:" + name + ",年龄:" + age + ",性别:" + gender + ",爱好:" + hobby;
    }
}

In this example, we created a Girlfriend class to represent a girlfriend, including four attributes of the girlfriend's name, age, gender and hobbies. In the main method of the GirlfriendArray class, we first define a Girlfriend array with a length of 4 to store girlfriend objects.

Then, get each girlfriend's information from the user input through a loop, and use the constructor to create the Girlfriend object. Store each created Girlfriend object into an array.

Next, we use a variable totalAge to add up the ages of all girlfriends. Then, calculate the average age by dividing by the length of the array.

Finally, we iterate through the array to see if each girlfriend's age is below the average, and if so, print it out and count the number.

At the same time, we rewrite the toString method in the Girlfriend class to return the information of the girlfriend object.

5, object array 5

Requirements: Define an array with a length of 3. The array stores 1~3 student objects as initialization data. The student numbers and names of the student objects are different.
Attributes of students: student number, name, age.
Requirement 1: Add a student object again, and make a unique judgment of the student number when adding it.
Requirement 2: After adding, traverse all student information.
Requirement 3: Delete student information by id, if it exists, delete it, if it does not exist, it means deletion failed.
Requirement 4: After deletion, traverse all student information.
Requirement 5: Query the student whose array id is "2023002", and if it exists, add his age + 1 year old.

The following is an object-oriented Java code example to create an array of student objects and implement the functions of adding, deleting, traversing and querying student information:

import java.util.Scanner;

public class StudentArray {
    
    
    public static void main(String[] args) {
    
    
        Scanner scanner = new Scanner(System.in);
        
        Student[] students = new Student[3];
        students[0] = new Student("2023001", "张三", 18);
        students[1] = new Student("2023002", "李四", 19);
        students[2] = new Student("2023003", "王五", 20);
        
        System.out.println("当前学生信息如下:");
        printStudents(students);
        
        System.out.println("请输入要添加的学生信息:");
        System.out.print("学号:");
        String id = scanner.next();
        System.out.print("姓名:");
        String name = scanner.next();
        System.out.print("年龄:");
        int age = scanner.nextInt();
        
        boolean isExist = false;
        for (int i = 0; i < students.length; i++) {
    
    
            if (students[i].getId().equals(id)) {
    
    
                isExist = true;
                break;
            }
        }
        
        if (isExist) {
    
    
            System.out.println("学号已存在,添加失败!");
        } else {
    
    
            Student newStudent = new Student(id, name, age);
            
            Student[] newStudents = new Student[students.length + 1];
            for (int i = 0; i < students.length; i++) {
    
    
                newStudents[i] = students[i];
            }
            newStudents[newStudents.length - 1] = newStudent;
            
            students = newStudents;
            
            System.out.println("添加成功!");
            System.out.println("当前学生信息如下:");
            printStudents(students);
        }
        
        System.out.print("请输入要删除的学生学号:");
        String deleteId = scanner.next();
        
        boolean isDeleted = false;
        for (int i = 0; i < students.length; i++) {
    
    
            if (students[i].getId().equals(deleteId)) {
    
    
                students[i] = null;
                isDeleted = true;
                break;
            }
        }
        
        if (isDeleted) {
    
    
            Student[] newStudents = new Student[students.length - 1];
            int newIndex = 0;
            for (int i = 0; i < students.length; i++) {
    
    
                if (students[i] != null) {
    
    
                    newStudents[newIndex] = students[i];
                    newIndex++;
                }
            }
            
            students = newStudents;
            
            System.out.println("删除成功!");
            System.out.println("当前学生信息如下:");
            printStudents(students);
        } else {
    
    
            System.out.println("学号不存在,删除失败!");
        }
        
        System.out.print("请输入要查询的学生学号:");
        String queryId = scanner.next();
        
        boolean isFound = false;
        for (int i = 0; i < students.length; i++) {
    
    
            if (students[i].getId().equals(queryId)) {
    
    
                students[i].setAge(students[i].getAge() + 1);
                isFound = true;
                break;
            }
        }
        
        if (isFound) {
    
    
            System.out.println("年龄已加1岁!");
            System.out.println("当前学生信息如下:");
            printStudents(students);
        } else {
    
    
            System.out.println("学号不存在!");
        }
    }
    
    public static void printStudents(Student[] students) {
    
    
        for (int i = 0; i < students.length; i++) {
    
    
            System.out.println(students[i].toString());
        }
    }
}

class Student {
    
    
    private String id;
    private String name;
    private int age;
    
    public Student(String id, String name, int age) {
    
    
        this.id = id;
        this.name = name;
        this.age = age;
    }
    
    public String getId() {
    
    
        return id;
    }
    
    public String getName() {
    
    
        return name;
    }
    
    public int getAge() {
    
    
        return age;
    }
    
    public void setAge(int age) {
    
    
        this.age = age;
    }
    
    @Override
    public String toString() {
    
    
        return "学号:" + id + ",姓名:" + name + ",年龄:" + age;
    }
}

In this example, we created a Student class to represent students, including three attributes of student ID, name and age. In the main method of the StudentArray class, we first define a Student array with a length of 3, and initialize the first 3 elements of the array.

Then, we obtain the student information to be added by input, and make a unique judgment of the student number. If the student ID already exists, the addition fails; otherwise, create a new Student object and add it to the new array.

Next, we obtain the student ID of the student to be deleted and make a judgment. If the student number exists, set the corresponding array element to null, and create a new array to store non-null elements, so as to realize deletion.

Then, we obtain the student ID of the student to be queried and make a judgment. If the student ID exists, add 1 year to the age of the corresponding student object.

Finally, we loop through and print all student information by calling the printStudents method.

At the same time, we rewrite the toString method in the Student class to return the information of the student object.

Guess you like

Origin blog.csdn.net/m0_62617719/article/details/132598475