JavaSE Notes (3) Remastered Edition

image-20220918121719900

Object-oriented basics

We have already learned process-oriented programming before, and we can also write simple programs by ourselves. We then need to understand object-oriented programming (Object Oriented Programming), which is an important content we need to learn in the Java language. Object-oriented is also an important feature of high-level languages.

Object-oriented is a watershed in the growth of novices. Some people understand it instantly, while some people cannot understand it until the end.

This chapter starts to become more difficult, so please be careful.

Classes and Objects

We have actually heard a lot about the concept of classes in our lives.

Humans, birds, fish... The so-called category is a description of a type of things. It is an abstract and conceptual definition. For example, birds generally refer to all animals with bird characteristics. For example, humans, different people have different personalities, different hobbies, different appearances, etc., but they are all fundamentally human, so they can be described abstractly as human beings.

The object is every individual that actually exists of a certain type of thing, so it is also called an instance. Each of us is an actual individual of human beings.

image-20220919203119479

Therefore, a class is an abstract concept of a person, and an object is a specific person.

  • A: Who took my phone?
  • B: It’s a person. (a certain category)
  • A: I also know it’s someone. Who is it specifically?
  • B: It’s XXX. (a specific object)

In Java, we can also program like this. We can define a class and then further create many instance objects of this class. Programming like this is called object-oriented programming .

Class and object creation

Earlier we introduced what a class is and what an object is. First, let's take a look at how to define a class.

For example, now we want to define a human, we can right-click srcthe directory and click Create New Class:

image-20220919204004526

When we name classes, we generally use English words with the first letter capitalized. Just like variable naming, no special characters can appear.

image-20220919204159248

As you can see, we now have two source files in our directory .java, one of which is Main.java created by default, and the other is the class we just created.

Let's take a look at what is written in a class after it is created:

public class Person {
   
    
    
    
}

As you can see, isn't this exactly the same format as the one written in the Main created at the beginning? Yes, Main is also a class, but we always use it as the main class, that is, the class where the main method is written. We will introduce the method later.

Now we have created a class. Since it is a human being, there must be some attributes related to it, such as name, gender, age, etc. So how can we add some attributes to this class?

We can define these properties directly into the class as member variables of the class (member variables are equivalent to the properties of this class, and these properties may be different after each instance is created).

public class Person {
   
    
       //这里定义的人类具有三个属性,名字、年龄、性别
    String name;   //直接在类中定义变量,表示类具有的属性
    int age;
    String sex;
}

Some friends may have questions, when will these variables be assigned values? In fact, these variables can only be used within a specific object.

So now that the attributes of human beings have been defined, we can try to create an instance object. The instance should correspond to a specific person:

new 类名();
public static void main(String[] args) {
   
    
    
    new Person();   //我们可以使用new关键字来创建某个类的对象,注意new后面需要跟上 类名()
  	//这里创建出来的,就是一个具体的人了
}

In fact, the entire process is:

image-20220919205550104

It's just that such an object is created here. We currently have no way to operate this object, such as wanting to modify or obtain the person's name, etc.

Object usage

Now that we know how to create an object, how do we access this object? For example, I want to view or modify its name now.

We can also use a variable to refer to an object, but a reference type variable stores a reference to the object, not the object itself:

public static void main(String[] args) {
   
    
    
  	//这里的a存放的是具体的某个值
  	int a = 10;
  	//创建一个变量指代我们刚刚创建好的对象,变量的类型就是对应的类名
  	//这里的p存放的是对象的引用,而不是本体,我们可以通过对象的引用来间接操作对象
    Person p = new Person();
}

As for why variables of object type store references to objects, for example:

public static void main(String[] args) {
   
    
    
    Person p1 = new Person();
    Person p2 = p1;
}

Here, we assign the variable p2 to the value of p1, so in fact we only pass the reference of the object, rather than a copy of the object itself. This is somewhat different from our previous basic data type. Both p2 and p1 point to the same object. (If you have studied C language, it exists like a pointer)

image-20220919211443657

We can test it:

public static void main(String[] args) {
   
    
    
    Person p1 = new Person();
    Person p2 = p1;
    System.out.println(p1 == p2);    //使用 == 可以判断两个变量引用的是不是同一个对象
}

But if we write it like this:

public static void main(String[] args) {
   
    
    
    Person p1 = new Person();   //这两个变量分别引用的是不同的两个对象
    Person p2 = new Person();
    System.out.println(p1 == p2);   //如果两个变量存放的是不同对象的引用,那么肯定就是不一样的了
}

In fact, the String type we used before is also a reference type, which we will discuss in detail in the next chapter. What we introduced in the previous chapter are basic types, and classes use reference types.

Now that we have a reference to the object, we can perform operations:

image-20220919210058797

We can directly access some properties of the object, which are those we have defined in the class. For different objects, the specific values ​​of these properties will be different.

For example, we can modify the name of the object:

public static void main(String[] args) {
   
    
    
    Person p = new Person();
    p.name = "小明";   //要访问对象的属性,我们需要使用 . 运算符
    System.out.println(p.name);   //直接打印对象的名字,就是我们刚刚修改好的结果了
}

Note that the properties of different objects are stored separately. Each object has its own space. Modifying the properties of one object will not affect other objects:

public static void main(String[] args) {
   
    
    
    Person p1 = new Person();
    Person p2 = new Person();
    p1.name = "小明";   //这个修改的是第一个对象的属性
    p2.name = "大明";   //这里修改的是第二个对象的属性
    System.out.println(p1.name);  //这里我们获取的是第一个对象的属性
}

Regarding variables of object type, we can also not reference any objects:

public static void main(String[] args) {
   
    
    
    Person p1 = null;  //null是一个特殊的值,它表示空,也就是不引用任何的对象
}

Note that if you do not reference any object, you definitely should not use this variable to operate the referenced object (there is no reference object, who am I to operate?)

Although this compiles successfully, problems may occur at runtime:

public static void main(String[] args) {
   
    
    
    Person p = null;   //此时变量没有引用任何对象
    p.name = "小红";   //我任性,就是要操作
    System.out.println(p.name);
}

Let's try running this code:

image-20220919213732810

At this time, an exception occurred while the program was running. Although we have not learned about the exception, you can understand the exception as a problem during the running of the program, and at this time, the program had to be terminated and exited.

What appears here is a null pointer exception, which is obviously caused by us operating a variable with a null value. In our future study, this anomaly will appear most frequently.

Let's look at the last question. After the object is created successfully, its properties are not assigned. But as we said before, variables need to be assigned before using them. So can they be accessed directly after the object is created?

public static void main(String[] args) {
   
    
    
    Person p = new Person();
    System.out.println("name = "+p.name);
    System.out.println("age = "+p.age);
    System.out.println("sex = "+p.sex);
}

Let's take a look at the results:

image-20220919214248053

We can see that if an object is created directly, the properties of the object will have initial values. If it is a basic type, the default value is unified (if it is 0boolean, the default value is false). If it is a reference type, the default value is false null.

Method creation and use

Earlier we introduced the definition of classes and the creation and use of objects.

Now that our class has attributes, we can set different attribute values ​​​​for these created objects, such as everyone's name is different, gender is different, age is different, etc. It's just that it's not enough to just have attributes. The object also needs to have certain behaviors, just like we humans can walk, jump, and think.

Objects can also perform some behaviors, which we can achieve by defining methods (called functions in C language)

A method is a collection of statements that exists to accomplish something. When you complete something, you can have results, or you can just do it without returning any results. For example, to calculate the sum of two numbers, we need to get the calculated result, so the method needs to have a return value; for another example, we just want to print the number on the console, and just print it, without giving me the result, so the method No return value is required.

The method is defined as follows:

返回值类型 方法名称() {
		方法体...
}

The first is the return value type, which means that after this method completes the task, the data type of the result obtained (can be a basic type or a reference type). Of course, if there is no return value and you just complete the task, you can use it to indicate that there is no return void. Value, for example, we now write a self-introduction behavior for humans:

public class Person {
   
    
    
    String name;
    int age;
    String sex;

  	//自我介绍只需要完成就行,没有返回值,所以说使用void
    void hello(){
   
    
    
      	//完成自我介绍需要执行的所有代码就在这个花括号中编写
      	//这里编写代码跟我们之前在main中是一样的(实际上main就是一个函数)
      	//自我介绍需要用到当前对象的名字和年龄,我们直接使用成员变量即可,变量的值就是当前对象的存放值
        System.out.println("我叫 "+name+" 今年 "+age+" 岁了!");
    }
}

Note that the method name can also be named casually, but the rules are similar to the naming of variables. Try to use words starting with lowercase letters. If there are multiple words, the camel case naming method is generally the most standardized.

image-20220920101033325

Now that we have defined a method (behavior) for humans, how can we make the object perform this behavior?

public static void main(String[] args) {
   
    
    
    Person p = new Person();
    p.name = "小明";
    p.age = 18;
    p.hello();    //我们只需要使用 . 运算符,就可以执行定义好的方法了,只需要 .方法名称() 即可
}

Executing a defined method like this is generally called a method call . Let's take a look at the effect:

image-20220919220837991

For example, now we want humans to learn addition operations, we can also do it by defining a method. However, to complete the addition operation, we need others to provide humans with two values ​​​​that participate in the addition operation, so here we have Parameters are needed:

//我们的方法需要别人提供参与运算的值才可以
//我们可以为方法设定参数,在调用方法时,需要外部传入参数才可以
//参数的定义需要在小括号内部编写,类似于变量定义,需要填写 类型和参数名称,多个参数用逗号隔开
int sum(int a, int b){
   
    
       //这里需要两个int类型的参数进行计算

}

So now that the parameters are passed in from the outside, how do we use them?

int sum(int a, int b){
   
    
       //这里的参数,相当于我们在函数中定义了两个局部变量,我们可以直接在函数中使用
    int c = a + b;   //直接c = a + b
}

So now that the calculation is complete, how do we transfer the results to the outside? First of all, the return value of the function is of type int. We only need to use returnkeywords to return a result of type int:

int sum(int a, int b){
   
    
    
    int c = a + b;
    return c;   //return后面紧跟需要返回的结果,这样就可以将计算结果丢出去了
  	//带返回值的方法,是一定要有一个返回结果的!否则无法通过编译!
}

Let’s test it out:

public static void main(String[] args) {
   
    
    
    Person p = new Person();
    p.name = "小明";
    p.age = 18;
    int result = p.sum(10, 20);    //现在我们要让这个对象帮我们计算10 + 20的结果
    System.out.println(result);    //成功得到30,实际上这里的println也是在调用方法进行打印操作
}

**Note:** The parameters written when the method is defined are generally called formal parameters, and the parameters actually passed in when calling the method are called actual parameters.

Does it feel more and more like we are really interacting with an object? As long as you have this experience, you have basically touched the object-oriented approach.

Regarding returnkeywords, we need to further introduce them.

After we use returnthe keyword, the method will end directly and return the result, so any code written after this is unreachable:

image-20220919222813469

Writing code later returnwill cause compilation to fail because there are unreachable statements.

If there are branch statements in our program, we must ensure that each branch has a return value:

image-20220919223037197

As long as any branch is missing returna statement, it will not be compiled normally. In short, all situations must be considered, and a return value must be provided in any case.

Of course, if the method does not return a value, we can also use returnstatements without any content. However, in this case, it is only used to quickly end the execution of the method:

void test(int a){
   
    
    
    if(a == 10) return;    //当a等于10时直接结束方法,后面无论有没有代码都不会执行了
    System.out.println("Hello World!");   //不是的情况就正常执行
}

Finally, let’s discuss the passing of parameters:

void test(int a){
   
    
       //我们可以设置参数来让外部的数据传入到函数内部
    System.out.println(a);
}

In fact, when passing parameters, the value of the parameter will be copied when the method is called. The parameter variable in the method is not the variable we passed in. Let's take the following example:

void swap(int a, int b){
   
    
       //这个函数的目的很明显,就是为了交换a和b的值
    int tmp = a;
    a = b;
    b = a;
}

So let’s test it:

public static void main(String[] args) {
   
    
    
    Person p = new Person();
    int a = 5, b = 9;   //外面也叫a和b
    p.swap(a, b);
    System.out.println("a = "+a+", b = "+b);   //最后的结果会变成什么样子呢?
}

Let's see what the result is:

image-20220919224219071

We found that the values ​​of a and b were not exchanged, but according to the logic of our method, they should be exchanged. Why is this? In fact, this is just copying the value to the variable in the function (equivalent to the assignment of the variable)

image-20220919224623727

So what we exchange is only a and b in the method, and parameter passing is only value passing. We have no way to directly operate on the outside a and b.

So friends, take a look at the following example:

void modify(Person person){
   
    
    
    person.name = "lbwnb";   //修改对象的名称
}
public static void main(String[] args) {
   
    
    
    Person p = new Person();
    p.name = "小明";     //先在外面修改一次
    p.modify(p);        //调用方法再修改一次
    System.out.println(p.name);    //请问最后name会是什么?
}

Let’s take a look at the results:

image-20220919224957971

No, didn't I just say that it is only passed by value? How come it can be modified successfully here?

Indeed, value transfer is also carried out here, but friends, please don’t forget that we have made it clear before that reference type variables only store references to objects, not the objects themselves. Then value transfer is performed here, which is equivalent to copying the reference of the object to the variable inside the method, and this internal variable is still the same object referenced, so operating within the method is equivalent to directly operating the outside definition object.

image-20220919225455752

Advanced use of methods

Sometimes there may be variables with the same names as member variables in our methods:

//我们希望使用这个方法,来为当前对象设定名字
void setName(String name) {
   
    
    
   
}

At this time, the name of the variable defined in the class is also the same name, so can we write it like this:

void setName(String name) {
   
    
    
    name = name;    //出现重名时,优先使用作用域最接近的,这里实际上是将方法参数的局部变量name赋值为本身
}

Let’s test it out:

public static void main(String[] args) {
   
    
    
    Person p = new Person();
    p.setName("小明");
    System.out.println(p.name);
}

We found that this seemed to have no effect, and the name was still unmodified. So when there are duplicate names, because by default the variable with the closest scope will be used first, how can we indicate that the variable to be used is a member variable of the class?

Person p = new Person();
p.name = "小明";    //我们之前在外面使用时,可以直接通过对象.属性的形式访问到

Similarly, if we want to access the properties of the current object in a method, we can use thiskeywords to explicitly represent the sample object of the current class itself:

void setName(String name) {
   
    
    
    this.name = name;   //让当前对象的name变量值等于参数传入的值
}

In this way, the modification can be successful. Of course, if there are no variables with duplicate names in the method, then by default, thiskeywords can not be used to clearly indicate the current object:

String getName() {
   
    
    
    return name;    //这里没有使用this,但是当前作用域下只有对象属性的name变量,所以说直接就使用了
}

Let's look at method overloading next.

Sometimes, the parameter types may be diverse, and our method needs to be able to handle multiple situations at the same time:

int sum(

Guess you like

Origin blog.csdn.net/qq_25928447/article/details/126988786