面向对象基础

一.类与对象

思维导图概览:

  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() {}
}
相关推荐
吾日三省吾码几秒前
JVM 性能调优
java
stm 学习ing5 分钟前
FPGA 第十讲 避免latch的产生
c语言·开发语言·单片机·嵌入式硬件·fpga开发·fpga
湫ccc1 小时前
《Python基础》之字符串格式化输出
开发语言·python
弗拉唐1 小时前
springBoot,mp,ssm整合案例
java·spring boot·mybatis
oi772 小时前
使用itextpdf进行pdf模版填充中文文本时部分字不显示问题
java·服务器
mqiqe2 小时前
Python MySQL通过Binlog 获取变更记录 恢复数据
开发语言·python·mysql
AttackingLin2 小时前
2024强网杯--babyheap house of apple2解法
linux·开发语言·python
少说多做3432 小时前
Android 不同情况下使用 runOnUiThread
android·java