首页 > 其他分享 >面向对象 (基础篇)

面向对象 (基础篇)

时间:2023-09-02 20:11:29浏览次数:39  
标签:String int 基础 System 面向对象 println public out

面向对象(基础篇)

1. 概述

1.1 什么是面向对象

  • 面向对象关注的是:在计算机程序设计的过程中,参照现实的事物,将事物的属性特征、行为特征抽象出来,用类来表示。
  • 代码结构:以为组织单位,每种事物都具备自己的属性行为/功能
  • 是一种设计者思维,适合解决复杂问题,代码扩展性强,可维护性高。

1.2 面向对象内容的三条主线

  • JAVA类及;类的成员:(重点)属性方法、(熟悉)构造器、代码块,内部类。
  • 面向对象的三大特征:封装继承多态,(抽象)。
  • 其他关键字的使用:this、super、package、import、static、final、interface、abstract...等

1.3 面向对象完成具体功能的操作流程(重要)

  1. 创建类,设计类的内部成员(属性,方法)
  2. 创建类的对象例如Phone phone = new Phone();(类的实例化)
  3. 通过对象,调用类中定义的方法和属性实现具体的功能
package com.ygc.oop.day01;

/**
 * @author: YGC
 * @createTime: 2023/08/22 0:18
 * @blogs: https://www.cnblogs.com/ygcDiary
 * @description: 手机测试
 */
public class PhoneTest {
    public static void main(String[] args) {
        //创建一个对象
        Phone phone = new Phone();
        //使用一个对象
        //通过类中定义的属性和方法,来使用一个对象
        phone.name = "YGC";
        phone.price = 100;
        phone.call();
        phone.playGame();
        phone.sendMessage("123");
        System.out.println("名字是" + phone.name + "价格" + phone.price);
    }
}

2. 基本元素(类,对象)

2.1 类

  1. :具有相同特征的事物的抽象描述,是抽象的、概念上的定义。

设计类,其实就是设计类的成员

  1. 类的实例化

    • 等价描述:类的实例化<=>创建类的对象<=>创建类的实例

    • 格式:类的类型 对象名 = 通过new创建对象的实体

    • //创建一个对象
      Phone phone = new Phone();
      

2.2 类的内部成员

  • 成员之一:属性(成员变量,filed)
  • 成员至二:(成员方法)方法,(函数、method)

2.3 类的成员之一:属性(成员变量,filed)

  1. 变量的分类:
  • 角度一:按照数据类型,基本数据类型:8种。引用数据类型:(数组,类,枚举,注解,记录)
  • 角度二:按照定义的位置分类,成员变量(属性),局部变量(方法内,构造器内,代码块内)
  1. 属性的几个称谓:成员变量,filed,

  2. 区分成员变量 vs 局部变量

3.1 相同点:

  • 都是变量,符合变量的定义规范
  • 必须先定义后使用
  • 有各自的作用域,出了作用域就失效

3.2 不同点:

① 类中声明的位置的不同:

  • 成员变量声明在
  • 局部变量声明在方法

② 在内存中分配的位置不同:

  • 成员变量存放在
  • 局部变量存储在

③ 生命周期:

  • 成员变量:随着对象的创建而创建

  • 局部变量:随着方法的栈帧进入栈中被激活,随着方法的栈帧出栈消亡

④ 作用域:

  • 成员变量:作用在整个类

  • 局部变量:只作用在定义局部变量的方法或构造器,代码块中

⑤ 是否可以有权限修饰符进行修饰:

  • public,protect,缺省,private
  • 只有成员变量可以被权限修饰符修饰

⑥ 是否有默认值:

  • 成员变量:具有初始值,与数组的初始值相同
  • 局部变量:没有初始值,定义时必须赋给初始值,才能使用,否则会报错
  • 注意:对于方法的形参而言,在调用方法时,给此形参赋值即可。
public void sleep(int hour) {
    System.out.println("人每天至少睡眠" + hour + "小时");
}
//在调用方法时给huor赋值,不赋值无法调用方法
p1.sleep(8);

2.3.1 任何一个数据类型都可以是成员变量的类型。

  • 举例
package com.ygc.oop.day02.filed02;

/**
 * @author: YGC
 * @createTime: 2023/08/22 23:40
 * @blogs: https://www.cnblogs.com/ygcDiary
 * @description: 声明一个MyDate类型,有属性:年year,月month,日day
 */
public class MyDate {
    int year;//年
    int mouth;//月
    int day;//日
}

package com.ygc.oop.day02.filed02;

/**
 * @author: YGC
 * @createTime: 2023/08/22 23:42
 * @blogs: https://www.cnblogs.com/ygcDiary
 * @description: 声明一个Employee类型,包含属性:编号、姓名、年龄、薪资、生日(MyDate类型)
 */
public class Employee {
    int id;//编号
    String name;//姓名
    int age;//年龄
    double salary;//薪资
    MyDate myDate;//生日***对象类型
}

package com.ygc.oop.day02.filed02;

/**
 * @author: YGC
 * @createTime: 2023/08/22 23:43
 * @blogs: https://www.cnblogs.com/ygcDiary
 * @description:在EmployeeTest测试类中的main()中,创建两个员工对象,并为他们的姓名和生日赋值,并显示
 */
public class EmployeeTest {
    public static void main(String[] args) {
        Employee employee = new Employee();
        MyDate myDate = new MyDate();
        Employee employee1 = new Employee();
        employee.name = "jack";
        /*另一种写法
         *  MyDate myDate1 = new MyDate();
            employee.myDate = myDate;
         * */
        employee.myDate = new MyDate();
        employee.myDate.mouth = 2;
        employee.myDate.day = 3;
        System.out.println(employee.name + "的生日是" + employee.myDate.mouth + "月" + employee.myDate.day + "日");
    }
}

2.4 类的成员之二:方法(method)

  • 方法是类或对象行为的抽象,用来完成具体的功能
  • 将功能封装在方法里面,可以实现代码的重用,减少代码的冗余,简化代码
  • JAVA中方法不能单独存在,必须声明在类中
  • 方法在使用完成之后就出栈。
  1. 方法的声明

    权限修饰符 [其他修饰符] 返回值类型 方法名(形参列表){
    //方法体
    }
    //[其他修饰符]不是必须要写的
    

​ 1.1 权限修饰符

  • public ,private,protect,缺省

    1.2 返回值类型:描述调用完此方法,是否需要返回一个结果

  • 无返回值:void

  • 有返回值:可以是基本数据类型,也可以是引用数据类型。

    • 在 有返回值 的类型中需要配合return+返回值类型的数据或常量
    • 【经验:】根据方法实现的功能,来判断是否需要返回值

​ 1.3 形参列表:是局部变量

  • 格式:(形参类型1 形参1,形参类型2 形参2,......)
  • 有形参:根据方法调用时不确定因素的个数,确定形参的个数
  • 无形参:不可以省略()
  1. return返回值
  • 作用1:结束一个方法
  • 作用2:结束方法的同时返回数据给方法的调用者
  • return后不能有执行语句

2.4.1 注意事项

  • JAVA中的方法,不调用不执行,调用一次,执行一次,在main开始之前,先在方法区加载类
  • 方法的定义不分先后顺序。在方法中可以调用其他的方法,不分前后。
  • 方法中可以调用方法或属性
  • 方法内不能定义方法,方法与方法是平级关系

举例:

package com.ygc.oop.day02.method;

/**
 * @author: YGC
 * @createTime: 2023/08/23 0:54
 * @blogs: https://www.cnblogs.com/ygcDiary
 * @description: 方法
 */
public class PersonMethod {
    public static void main(String[] args) {
        Person person = new Person();
        person.eat();
    }

    class Person {
        public void eat() {
            System.out.println("人吃饭");
            sleep(8);
        }

        public String sleep(int hour) {
            String info = "人每天至少睡眠" + hour + "小时";
            System.out.println(info);
            return info;
        }

    }
}

2.4.2 方法的使用

  • System.out.println(employee1.show());无返回值报错,有返回值不报错
package com.ygc.oop.day02.method;

/**
 * @author: YGC
 * @createTime: 2023/08/22 20:17
 * @blogs: https://www.cnblogs.com/ygcDiary
 * @description: 员工测试
 * 案例:
 * 声明员工类Employee,包含属性:编号id、姓名name、年龄age、薪资salary。
 * 声明EmployeeTest测试类,并在main方法中,创建2个员工对象,并为属性赋值,并打印两个员工的信息。
 */
public class EmployeeTest {
    public static void main(String[] args) {
        Employee employee1 = new Employee();
        employee1.id = 1;
        employee1.name = "jack";
        employee1.age = 24;
        employee1.salary = 6900;
        Employee employee2 = new Employee();
        employee2.id = 2;
        employee2.name = "rose";
        employee2.age = 25;
        employee2.salary = 8900;
        /* System.out.println("员工id" + employee1.id + "姓名" + employee1.name + "年龄:" + employee1.age + "薪资:" + employee1.salary);*/
        //替换为
        employee1.show();
//        System.out.println(employee1.show());无返回值报错,有返回值不报错
//        System.out.println("员工id" + employee2.id + "姓名" + employee2.name + "年龄:" + employee2.age + "薪资:" + employee2.salary);
        //替换为
        employee2.show();

    }
}

package com.ygc.oop.day02.method;

/**
 * @author: YGC
 * @createTime: 2023/08/22 20:17
 * @blogs: https://www.cnblogs.com/ygcDiary
 * @description: 员工
 * 声明员工类Employee,包含属性:编号id、姓名name、年龄age、薪资salary。
 */
public class Employee {
    int id;//编号
    String name;//姓名
    int age;//年龄
    double salary;//薪资

    public void show() {
        System.out.println("员工id" + id + "姓名" + name + "年龄:" + age + "薪资:" + salary);
    }
}

2.4.3 方法的内存结构

image-20230823115416674

2.4.4 方法的使用(练习)

2.4.4.1数组工具类
package com.ygc.oop.day02.methodExer.Exer04;

/**
 * @author: YGC
 * @createTime: 2023/08/23 12:44
 * @blogs: https://www.cnblogs.com/ygcDiary
 * @description: 数组工具类
 * 案例:
 * 根据上一章数组中的常用算法操作,自定义一个操作int[]的工具类。
 * 涉及到的方法有:求最大值、最小值、总和、平均数、遍历数组、复制数组、数组反转、数组排序(默认从小到大排序)、查找等
 */
public class MyArray {
    //属性
    int sum;
    int avg;
    int max;
    int min;

    /**
     * 求数组最大值
     *
     * @param arr
     */
    public void max(int[] arr) {
        max = arr[0];
        for (int i = 0; i < arr.length; i++) {
            if (max < arr[i]) {
                max = arr[i];
            }
        }
        System.out.println("最大值是:" + max);
    }

    /**
     * 最小值
     *
     * @param arr
     */
    public void min(int[] arr) {
        min = arr[0];
        for (int i = 0; i < arr.length; i++) {
            if (min > arr[i]) {
                min = arr[i];
            }
        }
        System.out.println("最小值是:" + min);
    }

    /**
     * 总和
     *
     * @param arr
     */
    public int sum(int[] arr) {
        sum = 0;
        for (int i = 0; i < arr.length; i++) {
            sum += arr[i];
        }
        return sum;
    }

    /**
     * 平均数
     *
     * @param arr
     */
    public void avg(int[] arr) {
        avg = sum(arr) / arr.length;
        System.out.println("平均值是:" + avg);
    }

    /**
     * 遍历数组
     *
     * @param arr
     */
    public void forArrays(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + "\t");
        }
        System.out.println();
    }

    /**
     * 复制数组
     *
     * @param arr
     */
    public void copyArrays(int[] arr) {
        int[] arr1 = new int[arr.length];
        for (int i = 0; i < arr.length; i++) {
            arr1[i] = arr[i];
        }
        forArrays(arr);
        System.out.println();
    }

    /**
     * 数组反转
     *
     * @param arr
     */
    public void rollBackArrays(int[] arr) {
        int temp = 0;
        for (int i = 0; i < arr.length / 2; i++) {
            temp = arr[i];
            arr[i] = arr[arr.length - 1 - i];
            arr[arr.length - 1 - i] = temp;
        }
        forArrays(arr);
        System.out.println();
    }

    /**
     * 数组排序
     *
     * @param arr
     */
    public void sortArrays(int[] arr) {
        int temp = 0;
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr.length; j++) {
                if (arr[i] < arr[j]) {
                    temp = arr[i];
                    arr[i] = arr[j];
                    arr[j] = temp;
                }
            }
        }
        forArrays(arr);
        System.out.println();
    }

    /**
     * 数组查找
     *
     * @param arr    数组
     * @param target 目标值
     */
    public void search(int[] arr, int target) {
        sortArrays(arr);
        int head = 0;
        int end = arr.length - 1;
        boolean isFlag = false;
        while (head <= end) {
            int mid = (head + end) / 2;
            if (arr[mid] > target) {
                end = mid - 1;
            } else if (arr[mid] < target) {
                head = mid + 1;
            } else {
                System.out.println("找到了" + mid);
                isFlag = true;
                break;
            }
        }
        if (!isFlag) {
            System.out.println("未找到");
        }
    }
}
  • 数组工具类测试
package com.ygc.oop.day02.methodExer.Exer04;

/**
 * @author: YGC
 * @createTime: 2023/08/23 13:00
 * @blogs: https://www.cnblogs.com/ygcDiary
 * @description: 数组工具类测试
 * 求最大值、最小值、总和、平均数、遍历数组、复制数组、数组反转、数组排序(默认从小到大排序)、查找等
 */
public class MyArrayTest {
    public static void main(String[] args) {
        MyArray myArray = new MyArray();
        int[] arr = {77, 88, 5, 6, 1, 3};
        //总和
        System.out.println("======总和=======");
        System.out.println(myArray.sum(arr));
        //最大值
        System.out.println("=======最大值======");
        myArray.max(arr);
        //最小值
        System.out.println("======最小值=======");
        myArray.min(arr);
        //平均值
        System.out.println("======平均值=======");
        myArray.avg(arr);
        //数组遍历
        System.out.println("======数组遍历=======");
        myArray.forArrays(arr);
        //数组复制
        System.out.println("=====数组复制========");
        myArray.copyArrays(arr);
        //数组反转
        System.out.println("=====数组反转========");
        myArray.rollBackArrays(arr);
        //数组排序
        System.out.println("=====数组排序========");
        myArray.sortArrays(arr);
        //数组查找目标值
        System.out.println("=====数组查找目标值========");
        myArray.search(arr, 3);
    }
}

2.4.5 方法的重载

在类中不允许定义相同的方法

  1. 定义:在同一个类中,允许存在多个重名,但参数列表不同的方法

  2. 两同一不同:

    • 两同:同一个中。方法名相同
    • 不同:参数列表不同
  3. 方法的重载与权限修饰符,形参名,返回值类型都没有关系

  4. 举例

    • package com.ygc.oop.day02.method_overload;
      
      /**
       * @author: YGC
       * @createTime: 2023/08/23 23:17
       * @blogs: https://www.cnblogs.com/ygcDiary
       * @description: 方法的重载
       */
      public class OverTest {
          public void add(int a) {
      
          }
      
          public void add(int a, int b) {
      
          }
      
          public void add(int a, String b) {
      
          }
      
          public void add(String b, int a) {
      
          }
      
          /*public void add(int m, int n){
      
          }*/
          /*public int add(String b, int a) {
              return 0;
          }*/
      }
      
      

      经典面试题

    • package com.ygc.oop.day02.method_overload;
      
      /**
       * @author: YGC
       * @createTime: 2023/08/23 23:39
       * @blogs: https://www.cnblogs.com/ygcDiary
       * @description: 方法的重载面试题
       */
      public class InterviewTest {
          public static void main(String[] args) {
              int[] arr = new int[]{1, 2, 3};
              System.out.println(arr);//地址值
              char[] arr1 = new char[]{'a', 'b', 'c'};
              System.out.println(arr1);//abc
              String[] arr2 = new String[]{"ass", "aaa", "ab"};
              System.out.println(arr2);//地址值
          }
      }
      //底层println方法发生了重载,char类型的打印会遍历数组
      

2.4.6 可变形参个数的方法

  1. 在定义方法时,形参类型确定,但是参数的个数不确定
  2. 格式:(参数类型...参数名)
  3. 可以构成重载(除了数组类型之外)
  4. 可以类比成数组
  5. 可变个数的形参必须放在参数列表的最后(int a,int...num)
  6. 可变个数的形参在同一个方法的参数列表,最多只能出现一次

举例:

package com.ygc.oop.day02.method_args;

/**
 * @author: YGC
 * @createTime: 2023/08/23 23:53
 * @blogs: https://www.cnblogs.com/ygcDiary
 * @description: 可变参数个数的方法
 */
public class ArgsTest {
    public static void main(String[] args) {
        ArgsTest argsTest = new ArgsTest();
        argsTest.print();//这是一个参数个数可变的方法111
        argsTest.print(11);//这是一个参数个数可变的方法222
        argsTest.print(111, 222);//这是一个参数个数可变的方法333

    }

    public void print(int... num) {
        System.out.println("这是一个参数个数可变的方法111");
    }

    public void print(int i) {
        System.out.println("这是一个参数个数可变的方法222");
    }

    public void print(int i, int j) {
        System.out.println("这是一个参数个数可变的方法333");
    }
}

  • 练习
package com.ygc.oop.day02.method_args;

/**
 * @author: YGC
 * @createTime: 2023/08/24 0:13
 * @blogs: https://www.cnblogs.com/ygcDiary
 * @description: 可变参数个数的方法的练习
 * 练习:可变形参的方法
 * n个字符串进行拼接,每一个字符串之间使用某字符进行分割,如果没有传入字符串,那么返回空字符串""
 */
public class ArgsTest01 {
    public static void main(String[] args) {
        ArgsTest01 argsTest01 = new ArgsTest01();
        String info = argsTest01.print("-", "hello", "world");
        System.out.println(info);
    }

    public String print(String operator, String... strs) {
        String result = " ";
        for (int i = 0; i < strs.length; i++) {
            if (i == 0) {
                result += strs[i];
            } else {
                result += operator + strs[i];
            }
        }
        return result;
    }
}

2.4.7 递归方法

  1. 定义一个方法,方法自己调用自己
  2. 分类: 直接递归,间接递归
  3. 说明:
  • 递归方法是一种隐式的循环

  • 如果这种循环不能停止,则会报错(栈内存溢出)

  1. 递归调用会占用大量的系统堆栈,内存耗用多,在递归调用层次多时速度要比循环慢的多,所以在使用递归时要慎重。

  2. 在要求高性能的情况下尽量避免使用递归,递归调用既花时间又耗内存。考虑使用循环迭代

2.4.7.1 练习
package com.ygc.oop.day02.recursion;

/**
 * @author: YGC
 * @createTime: 2023/08/24 14:57
 * @blogs: https://www.cnblogs.com/ygcDiary
 * @description: 递归方法
 */
public class RecursionExer01 {
    public static void main(String[] args) {
        RecursionExer01 recursionExer01 = new RecursionExer01();
        System.out.println(recursionExer01.method01(100));
        System.out.println(recursionExer01.method02(3));
        System.out.println(recursionExer01.method03(10));
        System.out.println(recursionExer01.method04(10));
        System.out.println(recursionExer01.method05(10));
    }

    //1-100的和
    public int method01(int num) {
        if (num == 1) {
            return 1;
        } else {
            return method01(num - 1) + num;
        }
    }

    //n!阶乘
    public int method02(int num) {
        if (num == 1) {
            return 1;
        } else {
            return num * method02(num - 1);
        }
    }

    /*举例3:已知有一个数列:f(0) = 1,f(1) = 4,f(n+2)=2*f(n+1) + f(n),其中n是大于0的整数,求f(10)的值。*/
    public int method03(int num) {
        if (num == 0) {
            return 1;
        } else if (num == 1) {
            return 4;
        } else {
            return 2 * method03(num - 1) + method03(num - 2);
        }
    }

    /*举例4:已知一个数列:f(20) = 1,f(21) = 4,f(n+2) = 2*f(n+1)+f(n),其中n是大于0的整数,求f(10)的值。*/
    public int method04(int num) {
        if (num == 20) {
            return 1;
        } else if (num == 21) {
            return 4;
        } else {
            return method04(num + 2) - 2 * method04(num + 1);
        }
    }

    /*举例5:计算斐波那契数列(Fibonacci)的第n个值,斐波那契数列满足如下规律*/
    public int method05(int num) {
        if (num == 1 || num == 2) {
            return 1;
        } else {
            return method05(num - 1) + method05(num - 2);
        }
    }

}

2.6 值传递机制

2.6.1 基本数据类型和引用数据类型的值传递机制

package com.ygc.oop.day02.vlaueTransfer;

/**
 * @author: YGC
 * @createTime: 2023/08/24 12:36
 * @blogs: https://www.cnblogs.com/ygcDiary
 * @description: 值传递机制
 */
public class ValueTransferTest {
    public static void main(String[] args) {
        //1.基本数据类型
        int m = 10;
        int n = m;//传递的是数据值
        System.out.println("m=" + m + ",n=" + n);//m=10,n=10
        m++;
        System.out.println("m=" + m + ",n=" + n);//m=11,n=10

        //2.引用数据类型
        int[] arr = {1, 2, 3, 4, 5, 6};
        int[] arr2 = arr;//传递的是地址值
        arr2[0] = 10;
        System.out.println(arr[0]);//10

        //3.对象类型
        Person person = new Person();
        person.id = 1001;
        Person person1 = person;//传递的是地址值
        person1.id = 1002;
        System.out.println(person.id);//1002
    }
}

class Person {
    int id;
}

2.6.2 方法的值传递机制

  • 实例引入
package com.ygc.oop.day02.vlaueTransfer;
package com.ygc.oop.day02.vlaueTransfer;

/**
 * @author: YGC
 * @createTime: 2023/08/24 12:57
 * @blogs: https://www.cnblogs.com/ygcDiary
 * @description: 方法的值传递机制
 */
public class ValueTransferTest01 {
    public static void main(String[] args) {
        ValueTransferTest01 valueTransferTest01 = new ValueTransferTest01();
        //基本数据类型
        int m = 10;
        valueTransferTest01.method01(m);
        System.out.println(m);//10
        //引用数据类型
        Person01 p = new Person01();
        p.age = 10;
        valueTransferTest01.method02(p);
        System.out.println(p.age);//11
    }

    public void method01(int m) {
        m++;
    }

    public void method02(Person01 p) {
        p.age++;
    }
}

class Person01 {
    int age;
}

2.6.2.1 总结(不管是基本数据类型,引用数据类型,还是方法,都是值传递的机制)
  1. 对于方法内声明的变量,出现赋值操作,分为两种情况
  • 如果是基本数据类型的变量:直接赋数据
  • 如果是引用数据类型的变量:赋值操作,赋值的是地址值

2.6.4 练习

package com.ygc.oop.day02.vlaueTransfer;

/**
 * @author: YGC
 * @createTime: 2023/08/24 13:19
 * @blogs: https://www.cnblogs.com/ygcDiary
 * @description: 方法的值传递机制练习
 */
public class ValueTransferTest03 {
    public static void main(String[] args) {
        Method method = new Method();
        method.m = 10;
        method.n = 20;
        method.swap(method);
        System.out.println("m= " + method.m + " n= " + method.n);//m =20,n =10
    }

}

class Method {
    int m;
    int n;

    public void swap(Method method) {
        int temp = 0;
        temp = method.m;
        method.m = method.n;
        method.n = temp;
    }

}
package com.ygc.oop.day02.vlaueTransfer;

/**
 * @author: YGC
 * @createTime: 2023/08/24 13:12
 * @blogs: https://www.cnblogs.com/ygcDiary
 * @description: 方法的值传递机制练习
 */
public class ValueTransferTest02 {
    public static void main(String[] args) {
        ValueTransferTest02 valueTransferTest02 = new ValueTransferTest02();
        int m = 10;
        int n = 20;
        //交换前
        System.out.println("m" + m + ",n" + n);
        valueTransferTest02.swap(m, n);//10,20
        //交换后
        System.out.println("m" + m + ",n" + n);//10,20
    }

    public void swap(int m, int n) {
        int temp = 0;
        temp = m;
        m = n;
        n = temp;
    }
}
package com.ygc.oop.day02.valueTransferTest;

/**
 * @author: YGC
 * @createTime: 2023/08/24 13:45
 * @blogs: https://www.cnblogs.com/ygcDiary
 * @description: 2. 定义一个类PassObject,在类中定义一个方法printAreas(),该方法的定义如下:
 * public void printAreas(Circle c, int time)。
 * 3. 在printAreas方法中打印输出1到time之间的每个整数半径值,以及对应的面积。
 * 例如,time为5,则输出半径1,2,3,4,5,以及对应的圆面积。
 * 4. 在main方法中调用printAreas()方法,调用完毕后输出当前半径值。程序运行结果如图所示
 */
public class PassObject {
    public static void main(String[] args) {
        PassObject passObject = new PassObject();
        Circle c = new Circle();
        passObject.printAreas(c, 5);
        System.out.println("now radius is:" + c.radius);
    }

    public void printAreas(Circle c, int time) {
        System.out.println("radius\t\tarea");
        for (int i = 1; i <= time; i++) {
            c.radius = i;
            System.out.println(c.radius + "\t\t\t" + c.findArea());
        }
        c.radius = time + 1;
    }
}

package com.ygc.oop.day02.valueTransferTest;

/**
 * @author: YGC
 * @createTime: 2023/08/24 13:42
 * @blogs: https://www.cnblogs.com/ygcDiary
 * @description: 圆
 * 1. 定义一个Circle类,包含一个double型的radius属性代表圆的半径,一个findArea()方法返回圆的面积。
 */
public class Circle {
    double radius;

    public double findArea() {
        return Math.PI * radius * radius;
    }
}

package com.ygc.oop.day02.valueTransferTest.exer02;

/**
 * @author: YGC
 * @createTime: 2023/08/24 14:11
 * @blogs: https://www.cnblogs.com/ygcDiary
 * @description: 真题
 */
public class InterviewTest {
    public static void main(String[] args) {
        int a = 10;
        int b = 10;
        InterviewTest interviewTest = new InterviewTest();
        interviewTest.method(a, b);
        System.out.println(a);
        System.out.println(b);
    }

    public void method(int a, int b) {
        a = 100;
        b = 200;
        System.out.println(a);
        System.out.println(b);
        //退出,不执行上面的代码
        System.exit(0);
    }
}

2. 7对象

对象:实际存在的该类事物,每个个体,是具体的,因此也称为实例(insrance)

2.7.1 对象在内存中分配涉及到的内存结构

  1. 栈:方法内定义的变量,存储在栈中。
  2. 堆:new出来的结构(比如:数组的实体,对象的实体)。包括对象的属性
  3. 方法区:存放类的字节码文件,(类的模板)

2..2 对象的内存解析

2..2.1 创建类的一个对象

image-20230822140844125

2..2.2 多个类的多个对象
image-20230822140646448

2..3 注意事项

Person p1 = new Person();
Person p2 = new Person();
//创建两个对象
  • 创建类的多个对象时,每个对象在堆空间中有一个对象的实体,每个对象的实体保存着一份属性
  • 如果修改对象的某个属性时不会影响其他对象的属性

【相互独立】

Person p1 = new Person();
Person p3 = p1;//赋值操作
//创建一个对象
  • 此时相当于将p1的地址值赋值给p3,在堆空间没有开辟新的空间存储新的对象属性,而是p1,p3公用一个对象的属性
  • 此时通过p3修改对象的属性,p1相对应的属性也会被修改。

2..4 对象数组 (与二维数组类似)

  1. 什么是对象数组:
  • 数组中的数据可以是基本数据类型,也可以是引用数据类型,因此,数组中的元素全部为对象,称为对象数组
  1. 举例:
  • String[],Person[].....
  1. 案例
package com.ygc.oop.day02.methodExer.Exer05;

/**
 * @author: YGC
 * @createTime: 2023/08/23 14:06
 * @blogs: https://www.cnblogs.com/ygcDiary
 * @description: 学生对象测试
 * 创建20个学生对象,学号为1到20,年级和成绩都由随机数确定。
 */
public class StudentTest {
    public static void main(String[] args) {
        Student[] students = new Student[20];
        Student student = new Student();
        student.inStudnet(students);
        System.out.println("============所有学生信息===========");
        student.showStudent(students);
        System.out.println("===========三年级的成绩============");
        student.showStudentWithState(students);
        System.out.println("===========排序后的成绩============");
        student.sortScore(students);

    }

}
package com.ygc.oop.day02.methodExer.Exer05;

/**
 * @author: YGC
 * @createTime: 2023/08/23 14:05
 * @blogs: https://www.cnblogs.com/ygcDiary
 * @description: 学生类
 * 案例:
 * 1)定义类Student,包含三个属性:学号number(int),年级state(int),成绩score(int)。
 * 2)创建20个学生对象,学号为1到20,年级和成绩都由随机数确定。
 * 问题一:打印出3年级(state值为3)的学生信息。
 * 问题二:使用冒泡排序按学生成绩排序,并遍历所有学生信息
 */
public class Student {
    int number;//成绩
    int state;//年级
    int score;//学号

    /**
     * 冒泡排序,排序学生的成绩
     *
     * @param students
     */
    public void sortScore(Student[] students) {
        Student temp = null;
        for (int i = 0; i < students.length; i++) {
            for (int j = 0; j < students.length; j++) {
                if (students[i].score < students[j].score) {
                    //交换学生的所有信息
                    temp = students[i];
                    students[i] = students[j];
                    students[j] = temp;
                }
            }
        }
        showStudent(students);
    }

    /**
     * 打印三年级的学生信息
     *
     * @param students
     */
    public void showStudentWithState(Student[] students) {
        for (int i = 0; i < students.length; i++) {
            if (students[i].state == 3) {
                System.out.print("学号:" + students[i].number + "\t");
                System.out.print("分数" + students[i].score + "\t");
                System.out.print("年级" + students[i].state + "\t");
                System.out.println();
            }
        }
    }

    /**
     * 打印学生信息
     *
     * @param students
     */
    public void showStudent(Student[] students) {
        for (int i = 0; i < students.length; i++) {
            System.out.print("学号:" + students[i].number + "\t");
            System.out.print("分数" + students[i].score + "\t");
            System.out.print("年级" + students[i].state + "\t");
            System.out.println();
        }
    }

    public void inStudnet(Student[] students) {
        for (int i = 0; i < students.length; i++) {
            students[i] = new Student();
            students[i].number = i + 1;
            students[i].state = (int) (Math.random() * 3) + 1;
            students[i].score = (int) (Math.random() * 100) + 1;
        }
    }
}
  1. 内存解析

image-20230823151412034

关键字

import:同名类导入,需要使用全类名的方式区分。

Date date = new Date();
java.sql.Date sqlDate = new java.sql.Date(123456);

3. 面向过程

3.1 什么是面向过程

  • 函数组织单位
  • 是一种执行者思维,适用于解决简单的问题。扩展能力差,不便于后期的维护。

4. 封装性

4.1 为什么需要封装性

  1. 高内聚,低耦合的体现:
  • 高内聚:类的内部数据和操作细节由自己完成,不允许外界干涉
  • 低耦合:仅仅暴露少量方法给外部使用。尽量方便外界调用。

高内聚、低耦合是软件工程中的概念,也是UNIX 操作系统设计的经典原则。

内聚,指一个模块内各个元素彼此结合的紧密程度;耦合指一个软件结构内不同模块之间互连程度的度量。内聚意味着重用和独立,耦合意味着多米诺效应牵一发动全身。

通俗的说:把该隐藏的隐藏,该暴露的暴露

4.2 如何实现数据封装

  1. 通过权限修饰符:
  • Java 提供了四个权限修饰符public,protected,缺省,private
  • 使用四种权限修饰符修饰类的内部成员,当这些成员被调用时体现可见性的大小
  1. 实际案例
package com.ygc.day01_constructor;

/**
 * @author: YGC
 * @createTime: 2023/08/25 0:08
 * @blogs: https://www.cnblogs.com/ygcDiary
 * @description: 封装性的测试
 */
public class AnimalTest {
    public static void main(String[] args) {
        Animal animal = new Animal();
        animal.name = "人";
        animal.setLegs(2);
        System.out.println(animal.getLegs());
        animal.eat();
    }
}

class Animal {
    private int legs;
    String name;

    public void setLegs(int l) {
        if (l > 0 && l % 2 == 0) {
            legs = l;
        } else {
            System.out.println("你输入的数据有误");
        }
    }

    public int getLegs() {
        return legs;
    }

    public void eat() {
        System.out.println("觅食");
    }
}

说明:

  1. 在正常的条件下legs是不能小于0的,为了避免外部类赋值错误,我们可以将legs属性私有化,使外部类无法调用该属性,在内部类中可以提供一个暴露的方法,给外部类实现赋值操作
  2. 同时内部类也提供了一个暴露的方法,可以让外部类得到该属性的值
  3. 这就是数据的封装。

4.3 权限修饰符的范围

  • public > protected > 缺省 > private
修饰符 本类内部 本包内 其他包的子类 其他包非子类
private × × ×
缺省 × × ×
protected ×
public

4.4 四种权限的使用

4.1 权限修饰符的使用规则:

  1. 类:只能用public 和缺省修饰
  2. 类的内部成员:可以用4种权限修饰符修饰

4.2 使用频率

  1. 开发中4种权限修饰使用频率
  • 比较高:public,private
  • 不常用:缺省,protected

4.3 封装性的体现

  • 私有化(private)属性,通提供公共的(public)get(),set()方法,对这个属性进行修改和获取

  • 将类种不需要对外暴露的方法私有化

  • 单例模式构造器私有化,避免在类的外部创建实例

4.4.1 练习

4.4.1.1 练习1,封装员工属性,并在键盘输入信息

package com.ygc.day01_constructor;

/**
 * @author: YGC
 * @createTime: 2023/08/25 12:45
 * @blogs: <a>https://www.cnblogs.com/ygcDiary</a>
 * @description: 员工
 * 案例:普通员工类
 * (1)声明员工类Employee,
 * - 包含属性:姓名、性别、年龄、电话,属性私有化
 * - 提供get/set方法
 * - 提供String getInfo()方法
 */
public class Employee {
    private String name;
    private char gender;
    private int age;
    private String telPhone;

    public void setName(String name1) {
        name = name1;
    }

    public String getName() {
        return name;
    }

    public void setGender(char gender1) {
        gender = gender1;
    }

    public char getGender() {
        return gender;
    }

    public void setAge(int age1) {
        if (age1 > 0 && age1 < 130) {
            age = age1;
        } else {
            System.out.println("你输入的年龄有误");
        }
    }

    public int getAge() {
        return age;
    }

    public void setTelPhone(String telPhone1) {
        telPhone = telPhone1;
    }

    public String getTelPhone() {
        return telPhone;
    }

    public String info() {
        return name + "\t" + gender + "\t" + age + "\t" + telPhone + "\t";
    }
}

package com.ygc.day01_constructor;

import java.util.Scanner;

/**
 * @author: YGC
 * @createTime: 2023/08/25 12:54
 * @blogs: <a>https://www.cnblogs.com/ygcDiary</a>
 * @description: 员工测试
 * 2)在测试类的main中创建员工数组,并从键盘输入员工对象信息,最后遍历输出
 */
public class EmployeeTest {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入员工的个数:");
        int employeeNumber = scanner.nextInt();
        Employee[] employees = new Employee[employeeNumber];
        for (int i = 0; i < employees.length; i++) {
            //这一步没有就是空指针异常,因为没有对象数组里的初始值是null
            employees[i] = new Employee();
            System.out.println("添加第" + (i + 1) + "个员工");
            System.out.print("姓名:");
            employees[i].setName(scanner.next());
            System.out.print("性别:");
            employees[i].setGender(scanner.next().charAt(0));
            System.out.print("年龄:");
            employees[i].setAge(scanner.nextInt());
            System.out.print("电话:");
            employees[i].setTelPhone(scanner.next());
        }
        System.out.println("员工列表");
        System.out.println("编号\t姓名\t性别\t年龄\t电话");
        for (int i = 0; i < employees.length; i++) {
            System.out.println((i + 1) + "\t" + employees[i].info());
        }

    }
}

5. 构造器(constructor)

凡是一个类,他都有自己的构造器

5.1 构造器概述

new对象,并在new对象的时候为实例变量赋值。

举例:Person p = new Person(“Peter”,15);

  1. 构造器的作用:
  • 搭配关键字new 创建类的对象
  • 在创建对象的同时,可以给相关的属性赋值
  1. 构造器的使用说明:
  • 构造器的格式
[修饰符] class 类名{
    [修饰符] 构造器名(){
    	// 实例初始化代码
    }
    [修饰符] 构造器名(参数列表){
        // 实例初始化代码
    }
}
  • 构造器名必须与它所在的类名必须相同

  • 没有返回值,所以不需要返回值类型,也不需要void

  • 构造器的修饰符只能是权限修饰符public,private,缺省,protected,不能是其他的

  • 创建类之后,在没有显示提供任何构造器的情况下,系统在编译时会自动提供一个空参的构造器

  • 默认的空参构造器的权限与该类的权限相同

  • 显示的创建了构造器,系统将不再提供默认的构造器

  • 构造器可以发生重载

  • 快捷键:在构建类的对象时,显示构造器的参数ctrl+p

5.2 举例

package com.ygc.day01_constructor.exer_constructor;

/**
 * @author: YGC
 * @createTime: 2023/08/25 14:05
 * @blogs: <a>https://www.cnblogs.com/ygcDiary</a>
 * @description: 学生
 * <p>
 * 案例:
 * (1)定义Student类,有4个属性:
 * String name;
 * int age;
 * String school;
 * String major;
 * (2)定义Student类的3个构造器:
 * - 第一个构造器Student(String n, int a)设置类的name和age属性;
 * - 第二个构造器Student(String n, int a, String s)设置类的name, age 和school属性;
 * - 第三个构造器Student(String n, int a, String s, String m)设置类的name, age ,school和major属性;
 */
public class Student {
    String name;
    int age;
    String school;
    String major;

    public Student(String n, int a) {
        name = n;
        age = a;

    }

    public Student(String n, int a, String s) {
        name = n;
        age = a;
        school = s;
    }

    public Student(String n, int a, String s, String m) {
        name = n;
        age = a;
        school = s;
        major = m;
    }
}

package com.ygc.day01_constructor.exer_constructor;

/**
 * @author: YGC
 * @createTime: 2023/08/25 14:09
 * @blogs: <a>https://www.cnblogs.com/ygcDiary</a>
 * @description: 学生测试_构造器
 * (3)在main方法中分别调用不同的构造器创建的对象,并输出其属性值。
 */
public class StudentTest {
    public static void main(String[] args) {
        Student student = new Student("ygc", 12);
        Student student1 = new Student("ygc", 12, "南京");
        Student student2 = new Student("ygc", 12, "南京", "计算机");
        System.out.println(student.name + "\t" + student.age);
        System.out.println(student1.name + "\t" + student1.age + "\t" + student1.school);
        System.out.println(student2.name + "\t" + student2.age + "\t" + student2.school + "\t" + student2.major);
    }
}

5.3 综合练习

  • 银行类
package com.ygc.day01_constructor.exerAll_account;

/**
 * @author: YGC
 * @createTime: 2023/08/25 14:27
 * @blogs: <a>https://www.cnblogs.com/ygcDiary</a>
 * @description: 账户
 * 案例:
 * 1、写一个名为Account的类模拟账户。该类的属性和方法如下图所示。
 * 该类包括的属性:账号id,余额balance,年利率annualInterestRate;
 * 包含的构造器:自定义
 * 包含的方法:访问器方法(getter和setter方法),取款方法withdraw(),存款方法deposit()。
 */
public class Account {
    private int id;
    private double balance;
    private double annualInterestRate;

    public Account() {

    }

    public Account(int i, double b, double a) {
        id = i;
        balance = b;
        annualInterestRate = a;
    }

    public void setId(int i) {
        id = i;
    }

    public int getId() {
        return id;
    }

    public void setBalance(int b) {
        balance = b;
    }


    public double getBalance() {
        return balance;
    }

    public void setAnnualInterestRate(double annualInterestRate1) {
        annualInterestRate = annualInterestRate1;
    }

    public double getAnnualInterestRate() {
        return annualInterestRate;
    }

    //取款方法
    public void withdraw(int outMoney) {
        if (outMoney > balance) {
            System.out.println("取款失败:余额不足");
        } else {
            System.out.println("取款成功:" + outMoney);
            System.out.println("余额:" + (balance -= outMoney));
        }
    }

    //存款方法deposit()
    public void deposit(int inMoney) {
        balance += inMoney;
        System.out.println("存款成功,本次存款金额为:" + inMoney);
    }

    //输出信息
    public String customerInfo(Customer customer) {
        return "Customer [" + customer.getFirstName() + "," + customer.getLastName() + "] has a account: id is " + getId() + "," + getAnnualInterestRate() + "is" + getAnnualInterestRate() + "balance is " + getBalance();
    }
}

  • 用户类
package com.ygc.day01_constructor.exerAll_account;

/**
 * @author: YGC
 * @createTime: 2023/08/25 14:39
 * @blogs: <a>https://www.cnblogs.com/ygcDiary</a>
 * @description: 用户
 * 2、创建Customer类。
 * a. 声明三个私有对象属性:firstName、lastName和account。
 * b. 声明一个公有构造器,这个构造器带有两个代表对象属性的参数(f和l)
 * c. 声明两个公有存取器来访问该对象属性,方法getFirstName和getLastName返回相应的属性。
 * d. 声明setAccount 方法来对account属性赋值。
 * e. 声明getAccount 方法以获取account属性。
 */
public class Customer {
    private String firstName;
    private String lastName;
    private Account account;
    
	//构造器,构造名字
    public Customer(String f, String l) {
        firstName = f;
        lastName = l;
    }

    public void setFirstName(String f) {
        firstName = f;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setLastName(String l) {
        lastName = l;
    }

    public String getLastName() {
        return lastName;
    }

    public void setAccount(Account account1) {
        account = account1;
    }

    public Account getAccount() {
        return account;
    }
}

  • 用户测试类
package com.ygc.day01_constructor.exerAll_account;

/**
 * @author: YGC
 * @createTime: 2023/08/25 14:48
 * @blogs: <a>https://www.cnblogs.com/ygcDiary</a>
 * @description: 用户测试
 * (1)创建一个Customer ,名字叫 Jane Smith, 他有一个账号为1000,余额为2000元,年利率为 1.23% 的账户。
 * (2)对Jane Smith操作。
 * 存入 100 元,再取出960元。再取出2000元。
 * 打印出Jane Smith 的基本信息:
 * 成功存入 :100.0
 * 成功取出:960.0
 * 余额不足,取款失败
 * Customer [Smith, Jane] has a account: id is 1000, annualInterestRate is 1.23%, balance is 1140.0
 */
public class CustomerTest {
    public static void main(String[] args) {
        Customer customer = new Customer("Jane", "Smith");
        //创建account
        Account account = new Account(100, 2000, 0.0123);
        //建立练习account<=>customer
        customer.setAccount(account);
        //按照实际需求,应该是用户拿着账号取钱
        customer.getAccount().deposit(100);
        customer.getAccount().withdraw(960);
        customer.getAccount().withdraw(2000);
        System.out.println(account.customerInfo(customer));
    }
}

6. 类中的属性赋值的过程

  1. 类的属性有哪些赋值方式:

    • ① 默认赋值

    • ② 显示赋值

    • ③ 构造器赋值

    • ④ 对象.方法 赋值

    • ⑤ 对象.属性赋值

顺序是:① - ② - ③ - ④/⑤

  1. 其中 ① - ② - ③只能执行一次
  2. ④/⑤可以多次调用执行

7. JavaBean

JavaBean就是一个公共的类,里面含有一个无参构造器,和Get,Set方法。方便后期动态的创建对象

  • 所谓JavaBean,是指符合如下标准的Java类:

    • 类是公共的

    • 有一个无参的公共的构造器

    • 有属性,且有对应的get、set方法

  • JavaBean举例

package com.ygc.day03_bean;

/**
 * @author: YGC
 * @createTime: 2023/08/26 0:28
 * @blogs: <a href="https://www.cnblogs.com/ygcDiary"></a>
 * @description: javaBean
 */
public class JavaBean {
    private int id;
    private String name;

    public JavaBean() {

    }

    public void setId(int i) {
        id = i;
    }

    public int getId() {
        return id;
    }

    public void setName(String n) {
        name = n;
    }

    public String getName() {
        return name;
    }

}

8. UML类图

  • 在软件开发中,使用UML类图可以更加直观地描述类内部结构(类的属性和操作)以及类之间的关系(如关联、依赖、聚合等)。

    • +表示 public 类型, - 表示 private 类型,#表示protected类型

    • 方法的写法:
      方法的类型(+、-) 方法名(参数名: 参数类型):返回值类型

    • 斜体表示抽象方法或类。

image-20230826003425357

标签:String,int,基础,System,面向对象,println,public,out
From: https://www.cnblogs.com/ygcDiary/p/17674142.html

相关文章

  • 【Python】Python语言基础
    好久没有更新啦~~那么趁着高中信息技术的学科,就更新一下下吧(嘿嘿)坐标:ZJ输入输出输入语句:input()默认读入的变量类型为string字符串输出语句:print()输出的内容如有多个变量用逗号隔开赋值赋值符号为=赋值符号每一次赋值,都是将=后面的内容直接覆盖到前面的变量中算术......
  • 图论基础
    图的存储图的存储:B3643ACCode:#include<iostream>#include<vector>#include<algorithm>usingnamespacestd;#definelllonglongconstintmaxn=1005;//邻接矩阵lla[maxn][maxn];//邻接表vector<ll>adj_list[maxn];lln,m;intmain(){c......
  • python基础语法之字符串
    字符串扩展1、字符串的三种定义方式单引号,双引号,三引号a='abc';b="sdf";c='''ewrc''';print(a,b,c);2、字符串的拼接#字符串字面量之间的拼接print("我是一名"+"大学生"+","+"学习智能医学工程");#字符串字面量和字符串变量的拼接name='......
  • 【WCH蓝牙系列芯片】-基于CH582开发板—基础外设输出PWM波形讲解
    ---------------------------------------------------------------------------------------------------------------------------------------------------------------------在WCH官方提供的CH583的EVT资源包中,我们可以找到PWMX的例程,这是一个8位的PWM输出,占空比和周期可调的......
  • 基础linux命令
    前言:由于在实际开发过程中服务器大多部署在linux系统下,所以特此来学习linux的基本操作1.1pwdpwd命令的目的是打印当前目录,告诉你目前在哪里比如我在kali终端中输入pwd,实际返回为/home/kali1.2lsls可以列出当前目录下有什么文件当然也可以查看不同目录的内容,比如ls文件地......
  • JSTL基础部分
    在使用JSTL时记得正确引入了JSTL标签库<%@taglibprefix="c"uri="http://java.sun.com/jsp/jstl/core"%>jstlif标签判断test属性表示判断的条件(使用EL表达式输出)<br><c:iftest="${12==12}">正确<br></c:if>jstl多路判断<......
  • 关于SpringBoot中引入html模板的问题的解决(基础)
    问题描述将相关的文件放置到resources/static文件夹目录下面,文件路径正确,但是一直应用不了问题解决原来是在引用的时候,需要在每个文件前面加上一个斜杠——/,这样就解决啦!......
  • ps基础配置
    认识ps简单设置首先进入ps  1、代表菜单栏2、代表属性栏3、代表工具栏4.、代表工作区5、代表调整面板首选项设置:CTRL+K(快捷键)   第二种方法:在菜单栏找到编辑-首选项-常规 文件处理:自动存储恢复信息的间隔 设置为5分钟  性能:内存使用情况:蓝色色条不要超过80......
  • java基础-流程控制-day04
    目录1.if单分支2.ifelse多分支3.ifelse双分支4.随机生成一定区间的整数5switch1.if单分支publicclassTestIf01{ publicstaticvoidmain(String[]args){ //对三个数(1-6)求和 intnum1=6; intnum2=6; intnum3=5; intsum=0; sum+=nu......
  • 使用AI写邮件-AI基础系列文章第18篇
    您的关注是对我最大的支持......