面向对象基础

一.类与对象

思维导图概览:

  1. 一个程序就是一个世界,世界(程序)有很多事物(属性,行为)

  2. 什么是类?什么是对象?类与对象的关系是什么?

1)类

i. 类是对象的数据类型,类是具有共同属性和共同行为的一类事物的归纳和抽象

ii. 类的组成

a. 属性:指事物的特征

b. 行为:指事物能进行的操作

2)对象就是类的一个实例。

简单理解:类是抽象化,而对象则把类的抽象化具体实现出来

3)类和对象的关系

i. 类是对现实生活中一类具有共同属性和行为的事物的抽象

ii. 对象是对类的抽象具体出来的实体

iii. 类和对象的关系示意图

  1. 类和对象的区别与联系

1)类是抽象的,概念上的,代表一类事物,比如:动物类,人类等等,它是数据类型

2)对象是具体的,实际的,代表一个具体事务,即是类的具体化

3)类是对象的模板,对象是类的一个个体,对应一个实例

  1. 一个小case快速了解类和对象
java 复制代码
public class Test {
    public static void main(String[] args) {
        Person person = new Person(); 
        //使用Person类,new Person()即是向类申请一个对象,申请的对象把它赋给person, person是一个对象
        //即person是Person的实例化  
    }
}


//Person类,一个类,Person是自定义类型,可以理解为C语言中的结构体
class Person() {
    int age; //成员变量/属性
    String name; //成员变量/属性
}
  1. 对象在内存中的存在形式
  1. 属性/成员变量/字段

1)了解:从概念上或叫法上来看:成员变量 = 属性 = filed(字段)---> 成员变量是用来表示属性的

java 复制代码
class Animal {
    int age;
    String name;
    //以上的这些就叫做成员变量/属性
}

2)属性是类的一个组成部分,一般是基本数据类型,也可以是引用类型(对象,数组)

3)属性的注意事项和细节讨论

i. 属性的定义语法和变量一样

ii. 属性的定义类型可以是任意类型,包含基本数据类型和引用类型

iii. 属性如果不赋值,有默认值

java 复制代码
权限修饰符 属性类型 属性名;
//注意:一般的局部变量我们需要给它赋初值,而成员变量则不需要赋予初值
//权限修饰符:public > protected > 默认 > private
//属性类型:八大类型,也可以是引用类型

|------------------------|---------------------|
| 属性类型 | 默认值 |
| boolean | false |
| byte, short, int, long | 0 |
| char | '\u0000' [十进制:0] |
| float, double | 0.0 |

java 复制代码
public class Test {
    public static void main(String[] args) {
        Cat cat = new Cat();
        System.out.println(cat.age);
        System.out.println(cat.c);
        System.out.println(cat.f);
        System.out.println(cat.b);
    }
}

class Cat() {
    int age; //默认为0
    char c; //默认为0
    double f; //默认为0.0
    boolean b; //默认为false
}
  1. 创建对象
  1. 先声明在创建

  2. 直接创建

java 复制代码
public class Test {
    public static void main(String[] args) {
        //先声明后创建对象
        Person p;
        p = new Person();
        
        //直接创建
        Person person = new Person();
    }
}

class Person {
    
}
  1. 访问属性

1)语法:对象名(对象的引用).属性名

java 复制代码
public class Test {
    public static void main(String[] args) {
        //直接创建对象
        Person p1 = new Person();
        
        //访问成员变量/属性
        p1.name = "jack";
        p1.age = 18;
        Person p2 = p1;                                                            
    }
}

class Person {
    //成员变量
    String name;
    int age;
}

2)类和对象的内存分布机制(重点)

  1. 类和对象的内存分布机制

1)Java内存的结构分析

i. 栈:一般存放基本数据类型(局部变量)

ii. 堆:存放对象/数组/字符串(new出的内存)

iii. 方法区:常量池(常量:字符串),类加载信息

2)Java创建对象的流程分析

java 复制代码
public class Test {
    public static void main(String[] args) {
        Person p = new Person();
        //new Person --> 在方法区种先加载Person类信息(属性和方法信息,只会加载一次
        //然后在堆中分配空间,进行默认初始化
        //把地址赋给p,p指向在堆中开辟的空间
        
        //把Person中的属性修改
        p.name = "jack";
        p.age = 10;
    }
}

class Person() {
    String name;
    int age;
}
  1. 成员变量与局部变量的区别

|---------|-----------------------|------------------------|
| 区别点 | 局部变量 | 成员变量 |
| 类中位置不同 | 方法内部/方法声明上 | 类中方法外 |
| 内存中位置不同 | 栈内存 | 堆内存 |
| 生命周期不同 | 随着方法的调用而存在, 方法调用完毕后销毁 | 随着对象的存在而存在, 随着对象的销毁而销毁 |
| 初始化不同 | 没有默认初始化,必须先定义,后使用 | 有默认初始化 |

  1. 思考以下代码输出什么?
java 复制代码
public class Test {
    public static void main(String[] args) {
        Person p1 = new Person();
        p1.name = "smith";
        p1.age = 18;
        
        Person p2;
        p2 = p1;
        System.out.println(p2.name);//?输出什么?
        p2.age = 20;
        p2 = null;
        System.out.println(p1.age);//?输出什么?
        System.out.println(p2.age);//?输出什么?
    }
}

class Person {
    String name;
    int age;
}

//答案:smith  20  出现异常

二.成员方法

思维导图概览:

  1. 什么是成员方法?

------ 我们要给类进行一些行为描述,这个就叫做成员方法。比如:People类会吃饭,睡觉,这时我们就要给People类定义成员方法。

  1. 一个小case快速了解成员方法
java 复制代码
public class Test {
    public static void main(String[] args) {
        Perosn p = new Person();
        //调用成员方法
        int res = p.getSum(10,20);
    }
}

class Person {
    String name;
    int age;
    
    //成员方法
    public int getSum(int num1, int num2) {
        return num1 + num2;
    }
}

3.方法调用总结

1)当程序执行到方法时,就会在栈中开辟一个独立的空间(栈空间)

2)当方法执行完毕,或者执行到return语句的时候,就会返回

3)方法调用结束时,会返回到调用的地方,然后会继续执行方法后面的代码

4)当main方法(栈)执行完毕,整个程序退出

  1. 成员方法的好处

1)提高代码的复用性

2)可以将实现的细节封装起来,然后共其他用户调用

  1. 成员方法的定义
java 复制代码
class Aniaml {
    
    public void print() {
        System.out.println("动物爱睡觉~~");    
    }
    
    //分析
    //成员方法由:访问修饰符 返回类型 方法名(形参列表1, 形参列表2, ......){//方法体组成
    //    语句;
    //    return 返回值;
    //}
}
  1. 成员方法的注意事项和细节讨论

1)一个方法最多只能有一个返回值或没有返回值,如果需要返回多个数据,可以返回一个数组

java 复制代码
class Teacher {
    public int getAge(String name, int age) {
        //return name,age; //错误,只能有一个返回值  
    }
    
    public void print() {
        //无返回值    
    }
}

2)返回类型可以是任意类型,包含基本类型或引用类型

java 复制代码
class People {
    //返回int类型
    public int print(int age){}
    
    //返回double类型
    public double sum(){}
    
    //返回String类型,String是引用类型
    public String getString() {}
}

3)如果方法要求有返回类型,则方法体中最后执行的语句必须为 return + 返回的值

java 复制代码
class People {
    public int getAge(int age) {
        return age;//必须返回相符合的类型    
    }
}

4)如果方法中的返回类型是void,则方法体中不能return + 返回一个具体值,只能使用return或不使用return语句

java 复制代码
class People {
    public void print() {
        //return age; //错误,不能返回值 
        return; //正确   
    }
}

5)访问修饰符(作用:控制方法的使用范围)

------ public > protected > 默认 > private

6)方法命名规则:遵守驼峰命名法 ------ 首字母小写,后面的英文单词的首字母大写

7)形参列表

i. 一个方法可以有0个参数或多个参数,若是多个参数,中间用逗号隔开

ii. 参数类型可以是任意类型,包含基本数据类型,但是传进方法中的数据和方法中的参数类型要相同或兼容

iii. 方法中定义的参数称为形式参数,方法调用时传入的参数称为实际参数

java 复制代码
public class Test {
    public static void main(Stirng[] args) {
        People p = new People();
        p.printNum(10,20);//实参和形参的数据类型要一致或兼容
        //10,20 --> 实参
    }
}

class People {
    String name;
    int age;
    
    //1.一个方法可以有0个参数或多个参数,若是多个参数,中间用逗号隔开
    //0个参数
    public void print() {
            
    }
    
    //多个参数,中间用逗号隔开
    public void set(int num1, int num2, int num3){}
    
    //2. 参数类型可以是任意类型,包含基本数据类型,但是传进方法中的数据和方法中的参数类型要相同或兼容
    public void printNum(int num1,int num2){}
    //int num1, int num2 ---> 形参
}

8)方法体:方法体内完成功能的具体语句,可以为输入、输出、变量、运算、分支、循环、方法调用,但是不能再定义方法,即方法不能嵌套定义

  1. 方法调用细节

1)同一个类中的方法调用:直接调用即可

2)跨类调用,需要通过对象名调用

3)静态方法不能调用非静态的方法,而非静态的方法可以调用静态方法和非静态方法

java 复制代码
public class Test {
    public static void main(String[] args) {
        People p = new People();
        //调用本类中的方法:直接调用
        set();
        //调用其他类中的方法:通过对象名调用
        p.print();                            
    }
    
    public static void set() {            
    }
}

class People {
    public void print() {}
}

三.成员方法的传参机制

  1. 基本数据类型的传参机制

------ 基本数据类型传递给成员方法的是值传递(值拷贝),形参的任何改变不影响实参

java 复制代码
public class Test {
    public static void main(String[] args) {
        Test test = new Test();    
        int num1 = 10;
        int num2 = 20;
        test.swap(num1,num2);
        
        System.out.println("num1 = " + num1 + " num2 = " + num2);
        //10 , 20
        //形参的改变不会影响实参   ---- > 值传递
    }
    
    public void swap(int num1, int num2) {
        int temp = num1;
        num1 = num2;
        num2 = temp;    
        System.out.println("num1 = " + num1 + " num2 = " + num2);
        //20 ,10
    }
}
  1. 引用数据类型的传参机制

------ 引用类型传递的是地址(址传递),形参的修改可以影响实参

java 复制代码
public class Test {
    public static void main(String[] args) {
        Test test = new Test();
        int[] arr = {1, 2, 3, 4, 5};
        
        for(int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + "\t");// 1 2 3 4 5                
        }  
        modifyArr(arr);
        
        Person p = new Person();
        p.name = "jack";
        p.age = 18;
        test.print(p); 
        System.out.println(p.age);//20
        System.out.println(p.name);//smith                                       
        //得出结论,若是址传递,则修改形参的值会影响实参    
    }
    
    public void modifyArr(int[] arr) {
        for(int i = 0; i < arr.length; i++) {
            arr[i] = 0;                    
        }    
        
        for(int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + "\t"); // 0 0 0 0 0                   
        }
    }
    
    public void print(Person p) {
        p.name = "smith";
        p.age = 20;
    }
}


class Person {
    String name;
    int age;
}
  1. 思考以下的问题
java 复制代码
public class Test {
    public static void main(String[] args) {
        Test test = new Test();
        B b = new B();

        b.name = "jack";
        b.age = 10;

        test.judge(b);

        System.out.println(b.age);//20

    }

    public void judge(B b) {
        //b.age = 20;
        //b =null;
        b = new B();
        b.age = 10000;
        System.out.println(b.age);//10000
    }
}

class B {
    String name;
    int age;
}
  1. 成员方法的返回类型是引用类型
java 复制代码
public class Test2 {
    public static void main(String[] args) {
        Test2 test2 = new Test2();
        B b = new B();

        b.name = "jack";
        b.age = 10;

        b = test2.judge(b);;

        System.out.println(b.age);//? ---> 18

    }

    //返回对象的类型 ---> 引用类型
    public B judge(B b) {
        b.age = 18;
        b.name = "jerry";
        return b;
    }
}

class B {
    String name;
    int age;
}

四.方法递归调用

思维导图概览:

  1. 什么是方法递归?

------ 方法递归就是方法自己调用自己,每次调用时传入不同的变量,递归有助于编程者解决复杂问题,同时可以让代码变的简洁

  1. 递归能解决什么问题?

1)各种数学问题,如:8皇后问题,汉诺塔问题,阶乘问题,迷宫问题等等

2)各种算法中也会使用到递归,比如快速排序,归并排序,二分查找,分治算法等

3)将用栈解决问题 ---> 递归代码比较简洁

  1. 一个小case快速了解递归
java 复制代码
public class Test {
    public static void main(String[] args) {
        Test test = new Test();
        int n = 10;
        int getFac = test.fac(n); 
        System.out.println(getFac);
    }
    
    public int fac(int n) {
        if(n == 1) {
            return 1;        
        } else {
            return n * fac(n - 1);        
        }                
    }
}
  1. 递归的重要规则

1)执行一个方法时,就创建一个新的受保护的独立空间(栈空间)

2)方法的局部变量是独立的,不会相互影响

3)如果方法中使用的是引用类型变量(数组,对象),就会共享该引用类型的数据

4)递归必须向退出递归的条件逼近,否则就是无限递归,出现StackOverFlowError

5)当一个方法执行完毕时,或者遇到return,就会返回,遵守谁调用就将结果返回给谁,同时当方法执行完毕或者返回时,该方法也就执行完毕

五.方法重载

思维导图概览:

  1. 什么是方法重载?

------ Java中允许同一个类中,多个同名方法的存在,但要求形参列表不一致

  1. 方法重载的好处

1)减轻了起名的负担

2)减轻了记名的麻烦

  1. 一个小case快速了解方法重载
java 复制代码
public class Test() {
    public static void main(String[] args) {
        Test test = new Test();
        test.print();
        test.print(10,20);
        test.print(10,20,30);    
    }
    public void print() {
        System.out.println("啥也没有~~");   
    }
    public void print(int num1, int num2) {
        System.out.println("num1 = " + num1 + " num2 = " + num2);   
    }
    
    public void print(int num1, int num2, int num3) {
        System.out.println("num1 = " + num1 + " num2 = " + num2 + " num3 = " + num3);   
    }
}
  1. 方法重载的注意事项和细节

1)方法名必须相同

2)形参列表必须不同(形参类型或个数或顺序,至少有一样不同,参数名无要求)

3)返回类型:无要求

java 复制代码
public class Test {
    public static void main(String[] args) {
        Test test = new Test();
        test.getSum();
        System.out.println(test.getSum(10,20));            
    }
    
    //形参列表不同,返回类型无要求
    public void getSum() {
        System.out.println("啥也没有哦~~");    
    }
    
    public int getSum(int num1, int num2) {
        return num1 + num2;    
    }
}

六.可变参数

思维导图概览:

  1. 概念:Java中允许同一个类中多个同名同功能但参数不同的方法,封装成一个方法,就可以通过可变参数实现

  2. 语法

访问修饰符 返回类型 方法名 (数据类型... 形参名){}

  1. 一个小case快速了解可变参数
java 复制代码
public class DemoOne {
    public static void main(String[] args) {
        DemoOne one = new DemoOne();
        int num1 = 20;
        int num2 = 30;
        int num3 = 40;

        //以下的三个的方法名相同,形参列表不同
        System.out.println(one.getSum(num1));
        System.out.println(one.getSum(num1,num2));
        System.out.println(one.getSum(num1,num2,num3));

    }

    public int getSum(int... arr) {
        int sum = 0;
        for (int i = 0; i < arr.length; i++) {
            sum += arr[i];
        }
        return sum;
    }
}
  1. 可变参数的注意事项和细节

1)可变参数的实参可以为0个或任意多个

java 复制代码
public class Test {
    public static void main(String[] args) {
        Test test = new Test();
        //可变参数为0个
        test.print(); 
        //可变参数为多个
        test.print("jack","marry","jerry","tom","smith","maria");                   
    }
    
    public void print(String... arr) {
        for(int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + "\t");        
        }    
    }
}

2)可变参数的实参可以为数组

java 复制代码
public class Test {
    public static void main(String[] args) {
        Test test = new Test();
        int[] arr = {1, 2, 3, 4, 5, 6, 7, 8};
        test.printArr(arr);
    }
    public void printArr(int... num) {
        for(int i = 0; i< num.length; i++) {
            System.out.print(num[i] + "\t");        
        }    
    }
}

3)可变参数的本质就是数组

4)可变参数可以和普通类型的参数一起放在形参列表,但可变参数必须保证放在最后

java 复制代码
public class Test {
    public static void main(String[] args) {
           
    }
    
    //错误代码,可变参数必须放在最后一个
    //public void show(int... arr, int x){} 

    //正确代码
    public void show(int x, int... arr){}
}

5)一个形参列表中只能出现一个可变参数

java 复制代码
public class Test {
    public static void main(String[] args) {
           
    }
    
    //错误代码:一个形参列表中只能出现一个可变参数
    //public void printArr(int... arr1, int... arr2) {} 
}

七.作用域

思维导图概览:

  1. 基本了解

1)在Java编程中,主要的变量就是属性(成员变量)和局部变量

2)我们说的局部变量一般是指在成员方法中定义的变量

3)Java中的作用域分类

i. 全局变量:也就是属性(成员变量),作用域为整个类

ii. 局部变量:除了属性之外的其他变量,作用域为在定义它的代码块中

4)全局变量(属性)可以不赋值,直接使用,因为有默认值;局部变量必须赋值后才能使用,因为没有默认值

  1. 一个小case快速了解全局变量和局部变量
java 复制代码
//一个小case了解什么是全局变量(属性)和局部变量
public class Test {
    int age;//全局变量/属性/成员变量 ---> 可直接使用,有默认值:0
    double num; //默认值:0.0
    
    public static void main(String[] args) {
        Test test = new Test();
        //全局变量可以直接使用,无需赋值
        System.out.println(test.age); //0
        System.out.println(test.num); //0.0
        
        test.printAge();
    }
    
    public void printAge() {
        int age; //局部变量,必须赋值才能使用
        //System.out.println(age); //程序报错,因为局部变量要赋值才能使用
        age = 18;
        System.out.println(age); //18            
    }
}
  1. 作用域的注意事项和细节

1)属性和局部变量可以重名,访问时遵循就近原则

java 复制代码
//属性和局部变量可以重名,访问时遵循就近原则
public class Test {
    int age = 10;
    
    public static void main(String[] args) {
        Test test = new Test();
        int age = 20;
        System.out.println(age); //20 --> 就近原则   
        test.printAge();         
    }
    public void printAge() {
        System.out.println(age); // 10
    }
}1

2)在同一个作用域中,两个变量不能重名【即重定义】

java 复制代码
public class Test {
    public static void main(String[] args) {
        //同一个作用域中(可以理解为在同一个方法中),两个局部变量不能重名
        int age = 20;
        int age = 30;    
    }
}

3)属性(成员变量/全局变量):生命周期较长,伴随着对象的创建而创建,伴随着对象的销毁而销毁;局部变量:伴随着它的代码块的执行而创建,伴随着代码块的结束而销毁(即一次方法调用过程中)

java 复制代码
public class Test {
    public static void main(String[] args) {
        Test test = new Test();
        //方法中的局部变量:伴随着它的代码块的执行而创建,伴随着代码块的结束而销毁
        test.show();
        
        //属性(成员变量/全局变量):伴随着对象的创建而创建,伴随着对象的销毁而销毁
        Animal dog = new Animal();
        dog.age = 10;
        System.out.println(dog.age); // 10      
    }
    
    public void show() {
        String name = "Tiger"; //局部变量
        System.out.println(name); // Tiger 
    }
}

class Animal {
    int age = 10;
}

4)作用域范围不同

i. 全局变量/属性:可以被本类使用,或被其他类使用(通过对象调用)

ii. 局部变量:只能在本类中对应的方法使用

java 复制代码
public class Test {
    public static void main(String[] args) {
        Test test = new Test();
        //num是局部变量,只能在main方法中使用
        int num = 20;

        //Animal中的age被其他类使用
        Animal a = new Animal();
        a.age = 30;
        System.out.println(a.age); //30
    }
}

class Animal {
    int age = 10;

    //1. 全局变量age被本类使用
    public void getAge() {
        age = 40;
    }
}

5)修饰符不同

i. 全局变量/属性:可以添加访问修饰符(public > protected > 默认 > private)

ii. 局部变量不可以加修饰符

java 复制代码
public class Test {
    public int age = 30; //全局变量可以加访问修饰符
     
    public static void main(String[] args) {
        //public int age = 20; //局部变量不能使用访问修饰符                
    }
}

八.构造方法/构造器

思维导图概览:

  1. 构造器了解

------ 构造方法又叫构造器,是类的一种特殊的方法,它的主要作用是完成对新对象的初始化
特点如下:

1)方法名和类名相同

2)没有返回类型

3)在创建对象的时候,系统会自动的调用该类的构造器完成对象的初始化

  1. 基本语法
java 复制代码
修饰符 方法名(形参列表){
    方法体;
}
//1.修饰符可以是默认,也可以是public,protected,private
//2.构造器不能有返回值,也不能写void
//3.方法名必须和类名相同
//4.参数列表和成员方法一样的规则
//5.构造器的调用,由系统来完成
  1. 一个小case快速了解构造器
java 复制代码
public class Test {
    public class Test {
    public static void main(String[] args) {
        //"smith", 80 -- > 是对类进行初始化
        Animal animal = new Animal("smith", 80);

        System.out.println(animal.name); //smith
        System.out.println(animal.age); //80
    }
}

class Animal {
    String name;
    int age;

    //注意:1.构造器不能有返回值,也不能写void
    //2.构造器的名称必须和类名一致
    //3.String n, int a是形参列表
    public Animal(String n, int a) {
        name = n;
        age = a;
    }
}
  1. 构造器的注意事项和细节

1)一个类可以定义多个不同的构造器,即构造器重载

2)构造器名和类名必须相同

3)构造器无返回值

java 复制代码
class Demo {
    //无参构造器:构造器名(Demo),类名(Demo)
    public Demo() {}
    //一个参数构造器:构造器名(Demo),类名(Demo)
    public Demo(int num) {}
    //多个参数构造器:构造器名(Demo),类名(Demo)
    public Demo(int num1, int num2, int num3.....) {}
    
    //注意:从上面看出我们的构造器名和类名必须相同
    //注意:构造器中我们不能给予返回值,如果给予返回值,那就不是构造器,导致程序崩溃
    //public void Demo() {} //程序错误
}

4)构造器是完成对象的初始化,并不是创建对象

java 复制代码
public class Test {
    public static void main(String[] args) {
        //"smith", 80 -- > 是对类进行初始化
        Animal animal = new Animal("smith", 80);

        System.out.println(animal.name); //smith
        System.out.println(animal.age); //80
    }
}

class Animal {
    String name;
    int age;

    //使用这个构造器后,可以看出本类中的name,age均被初始化
    public Animal(String n, int a) {
        name = n;
        age = a;
    }
}

5)在创建对象的时候,系统会自动调用该类的构造器

6)如果没有给定构造器,系统会自动的给类生成一个默认的无参构造器

java 复制代码
public class Test {
    public static void main(String[] args) {
        //在创建Animal对象的时候,系统默认调用Animal的构造器
        Animal animal = new Animal();
        //发现Animal类中无给定构造器,系统会自动的给类生成一个默认的无参构造器
    }
}

class Animal {
    String name;
    int age;
    
    //系统发现Animal类中无给定构造器,给定默认构造器
    // public Animal(){}
}

7)一旦给定了构造器,默认的构造器就不存在了,被我们给定的构造器覆盖了,则我们不能再使用默认的无参构造器,除非显示的定义一下

java 复制代码
public class Test {
    public static void main(String[] args) {
        Animal animal = new Animal("jack", 30);
    }
}

class Animal {
    String name;
    int age;
    
    //我们写出这个构造器的时候,系统的原先的无参构造器被覆盖了,若是还想使用,则显示定义
    public Animal(String n, int a) {
        name = n;
        age = a;    
    }
    
    //显示定义无参构造器
    public Animal() {}
}

九.对象的创建流程

思维导图概览:

java 复制代码
public class Test {
    public static void main(String[] args) {
        Person p = new Person("jack", 18);   
    }
}

class Person {
    //成员变量
    int age;
    String name;
    //构造器
    Person(String n, int a) {
        name = n;
        age = a;    
    }
}

//流程分析
//1.在方法区中加载Person类信息,只会加载一次
//2.在堆中分配空间(地址)
//3.完成对象的初始化、构造器的初始化(age = 0, name = null)
//4.对象在堆中的地址,返回给p(p是对象名,也可以理解是对象的引用)

十.this关键字

思维导图概览:

  1. 什么是this关键字?

------ Java虚拟机会给每个对象分配this,代表当前对象。那个对象调用,this就代表谁

  1. 一个小case快速了解this
java 复制代码
public class Test {
    public static void main(String[] args) {
        Animal animal = new Animal("Tiger",10);
        animal.print();
    }
}

class Animal {
    String name;
    int age;
    
    public Animal(String name, int age) {
        //this.name代表当前对象(animal)的age
        this.name = name;
        this.age = age;    
    }
    
    public void print() {
        //当中的this.age和this.name都代表当前对象(animal)的name和age
        System.out.println(this.name + "已经" + this.age + "岁了");    
    }
}
  1. this的注意事项和细节

1)this关键字可以用来访问本类的属性、方法、构造器

java 复制代码
public class Test {
    public static void main(String[] args) {
        Person p = new Person("jack", 30);

    }
}

class Person {
    String name;
    int age;

    public Person() {
    }

    public Person(String name, int age) {
        //使用this访问本类的另外一个构造器
        this();
        this.name = name;
        this.age = age;
    }

    public void print() {
        //使用this访问本类的属性
        System.out.println(this.name + this.age + "岁了~~");
    }

    public void getPrint() {
        //使用this访问本类中的方法
        this.print();
    }
}

2)this用于区分当前类的属性和局部变量

java 复制代码
public class Test {
    public static void main(String[] args) {
        Animal animal = new Animal("Tiger",10);
    }
}

class Animal {
    String name;
    int age;
    
    public Animal(String name, int age) {
        //这样的话我们无法区分那个是形参(局部变量),那个是Animal的name和age
        name = name;
        age = age;   
        //我们使用this来区分区别变量和全局变量
        this.name = name;
        this.age = age;          
    }
}

3)访问成员方法的语法:this.方法名(参数列表)

4)访问构造器语法:this(参数列表);注意:只能在构造器中使用(即只能在构造器中访问另外一个构造器,必须放在第一条语句)

java 复制代码
class Person {
    String id;
    int age;
    
    public Person(){}
    
    public Person(String id, int age) {
        this();//访问另外一个构造器,this必须放在第一句
    }
}

5)this不能在类定义的外部使用,只能在类定义的方法中使用或构造器中使用

java 复制代码
class Animal {
    String name;
    int age;
    
    public Animal(String name, int age) {
        this.name = name;
        this.age = age;    
    }
    
    //this.age = 18;//错误,this不能在外部(构造器外,方法外)使用
    
    public void print() {
        this.age = 18; //对            
    }
}

十一.权限修饰符

思维导图概览:

  1. 权限修饰符了解

------ Java提供四种访问控制修饰符号,用于控制方法和属性(成员变量)的访问权限

1)public:公开级别

2)protected:受保护级别

3)默认级别:方法的前面/成员变量的前面什么都不写,即是默认级别

4)private:私有级别

  1. 权限修饰符的访问范围

|-----------|----|----|----|-----|
| 访问权限修饰符 | 同类 | 同包 | 子类 | 不同包 |
| public | √ | √ | √ | √ |
| protected | √ | √ | √ | × |
| 默认 | √ | √ | × | × |
| private | √ | × | × | × |

  1. 权限修饰符的注意事项和细节

1)修饰符可以用来修饰类中的属性,成员方法和类

2)只有默认和public才能修饰类,并遵循上述表格中的访问权限范围

3)成员方法的访问规则和属性完全相同

  1. 一个小case快速了解权限修饰符
java 复制代码
//Person类是默认类
class Person {
    public int num; //公开
    protected char sex; //受保护
    int age; //默认
    private String name; //私有
    
    //公开的构造器
    public Person() {}
    //默认的构造器
    Person() {}
    ......
    
    //公开的方法
    public void print() {}
    //私有的方法
    private void print() {}
}
相关推荐
王伯爵几秒前
<packaging>jar</packaging>和<packaging>pom</packaging>的区别
java·pycharm·jar
一朵好运莲6 分钟前
React引入Echart水球图
开发语言·javascript·ecmascript
Eiceblue19 分钟前
使用Python获取PDF文本和图片的精确位置
开发语言·python·pdf
Q_192849990623 分钟前
基于Spring Boot的个人健康管理系统
java·spring boot·后端
xianwu54327 分钟前
反向代理模块。开发
linux·开发语言·网络·c++·git
xiaocaibao77733 分钟前
Java语言的网络编程
开发语言·后端·golang
木向1 小时前
leetcode22:括号问题
开发语言·c++·leetcode
comli_cn1 小时前
使用清华源安装python包
开发语言·python
筑基.1 小时前
basic_ios及其衍生库(附 GCC libstdc++源代码)
开发语言·c++
m0_748245171 小时前
Web第一次作业
java