目录
封装
封装引入
private修饰符
this关键字
构造函数
JavaBean
标准JavaBean
JavaBean中的成员与数据库的关系
static关键字
static基本使用
static关键字访问特点
可变参数
对象数组与传值/址调用
对象数组
传值调用与传址调用
命令行参数
封装
封装引入
面向对象三大特性:封装、继承和多态
在Java中,封装是将一类事物的属性和方法放到一个class类中,例如Person类
 package com.epsda.java_class;
 
 public class Person {
     // 属性
     String name;
     int age;
     Birthday birthday;
 
     // 方法
     public void print(){
         System.out.println("name = " + name + " " + "age = " + age + " " + "birthday: " + birthday.year + "/" + birthday.month + "/" + birthday.day);
     }
 }但是Person类中的成员此时可以被随意访问和修改,为了防止这种问题,从而出现了访问修饰符private
private修饰符
 
使用private修饰符修饰的成员无法在类外被访问
package com.epsda.java_private;
 
 public class Person {
     // 被priavte修饰后无法在类外访问
     private int age;
     private String name;
 
 }
 
 package com.epsda.java_private;
 
 public class java_private {
     public static void main(String[] args) {
         Person person = new Person();
         // 被priavte修饰后无法在类外访问
         // person.age = 10;
         // person.name = "张三";
 
     }
 }但是封装之后需要对外提供使用的接口,在Java中称为get和set方法
this关键字
 
当方法的局部变量和成员变量重名时,可以使用this关键字指代成员变量,防止出现重名时的访问均为局部变量
this关键字指代的是调用对象,其地址和对象地址相同
package com.epsda.java_private;
 
 public class Person {
     // 展示this和对象地址
     public void showThis(){
         System.out.println(this);
     }
 }
 
 package com.epsda.java_private;
 
 public class java_private {
     public static void main(String[] args) {
         Person person2 = new Person();
         System.out.println(person2);
         person2.showThis();
     }
 }
 
 输出结果:
 com.epsda.java_private.Person@154617c
 com.epsda.java_private.Person@154617c结合get/set方法,this关键字的使用
package com.epsda.java_private;
 
 public class Person {
     // 被priavte修饰后无法在类外访问
     private int age;
     private String name;
 
     // 提供get和set方法
     public int getAge() {
         return age;
     }
 
     public void setAge(int age) {
         this.age = age;
     }
 
     public String getName() {
         return name;
     }
 
     public void setName(String name) {
         this.name = name;
     }
 }构造函数
Java中创建对象时需要使用new,而new后面的实际上是在调用构造函数构造对象,如果类没有显式写构造函数,那么JVM会隐式生成一个无参数的构造函数,但是如果显式写了构造函数(包括无参数和有参数),那么编译器就不会再生成
 package com.epsda.java_private;
 
 public class Person {
     // 被priavte修饰后无法在类外访问
     private int age;
     private String name;
 
     // 构造函数
     // 无参数构造
     public Person() {
     }
 
     // 有参数构造
     public Person(int age, String name) {
         this.age = age;
         this.name = name;
     }
 }当无参数构造函数和有参数构造函数共存时,此时出现方法重载现象,如果创建对象不传入参数,则调用无参数构造函数,否则调用有参数构造函数
package com.epsda.java_private;
 
 
 /**
  * ClassName: java_private
  * Package: com.epsda.java_private
  * Description:
  *
  * @author 憨八嘎
  * @version v1.0
  */
 public class java_private {
     public static void main(String[] args) {
         // 调用无参数构造函数
         Person person = new Person();
         // 通过get方法获取属性值
         System.out.println(person.getName() + " " + person.getAge());
         // 通过set方法设定属性值
         person.setAge(10);
         person.setName("李四");
         System.out.println(person.getName() + " " + person.getAge());
 
         // 调用有参数构造函数
         Person person1 = new Person(10, "张三");
         // 通过get函数获取属性值
         System.out.println(person1.getName() + " " + person1.getAge());
     }
 }
 
 输出结果:
 null 0
 李四 10
 张三 10
 JavaBean
标准JavaBean
JavaBean是Java语言编写类的一种标准规范。符合JavaBean 的类,要求:
-  类必须是具体的(非抽象 abstract)和公共的,public class类名
-  并且具有无参数的构造方法,有参构造 
-  成员变量私有化,并提供用来操作成员变量的 set和get方法。
在Java项目中,一般有以下包及对应的功能
-  com.epsda.controller-> 专门放和页面打交道的类(表现层)
-  com.epsda.service-> 专门放业务处理的类 (业务层)
-  com.epsda.dao-> 专门放和数据库打交道的类(持久层)
-  com.epsda.pojo-> 专门放JavaBean类
-  com.epsda.utils-> 专门放工具类
对于上方的Person类来说,即为一个标准的JavaBean结构
 package com.epsda.java_private;
 
 /**
  * ClassName: Person
  * Package: com.epsda.java_private
  * Description:
  *
  * @author 憨八嘎
  * @version v1.0
  */
 public class Person {
     // 被priavte修饰后无法在类外访问
     private int age;
     private String name;
 
     // 构造函数
     // 无参数构造
     public Person() {
     }
 
     // 有参数构造
     public Person(int age, String name) {
         this.age = age;
         this.name = name;
     }
 
     // 提供get和set方法
     public int getAge() {
         return age;
     }
 
     public void setAge(int age) {
         this.age = age;
     }
 
     public String getName() {
         return name;
     }
 
     public void setName(String name) {
         this.name = name;
     }
 }JavaBean中的成员与数据库的关系
-  类名 -> 表名 
-  属性名 -> 列名 
-  对象 -> 表中每一行数据 
-  属性值 -> 表中单元格中的数据 
对于Person类来说,Person表结构如下
| name | age | 
|---|---|
| 张三 | 10 | 
| 李四 | 10 | 
static关键字
 
static基本使用
 
当一个成员是多个对象共享时,可以使用static关键字对该成员进行修饰
static修饰的成员可以直接使用类名调用
定义一个Student类,教室学生共用,所以可以设置为static,其他为每一个对象特有的则可以不设置为static
 package com.epsda.java_static;
 
 /**
  * ClassName: Student
  * Package: com.epsda.java_static
  * Description:
  *
  * @author 憨八嘎
  * @version 1.0
  */
 public class Student {
     // 学生特有属性
     private String name;
     private int age;
     // 学生共有属性
     private static int classroom;
 
     public Student() {
     }
 
     public Student(String name, int age) {
         this.name = name;
         this.age = age;
     }
 
     public String getName() {
         return name;
     }
 
     public void setName(String name) {
         this.name = name;
     }
 
     public int getAge() {
         return age;
     }
 
     public void setAge(int age) {
         this.age = age;
     }
 
     public static int getClassroom() {
         return classroom;
     }
 
     public static void setClassroom(int classroom) {
         Student.classroom = classroom;
     }
 
     public void print() {
         System.out.println(name + " " + age + " " + classroom);
     }
 }测试类
package com.epsda.java_static;
 
 /**
  * ClassName: java_static
  * Package: com.epsda.java_static
  * Description:
  *
  * @author 憨八嘎
  * @version 1.0
  */
 public class java_static {
     public static void main(String[] args) {
         Student student1 = new Student("张三", 18);
         Student student2 = new Student("李四", 20);
         // 两个学生在一个班级时,直接用类名调用,而不是每一个单独设置
         Student.setClassroom(112);
 
         student1.print();
         student2.print();
     }
 }
 
 输出结果:
 张三 18 112
 李四 20 112static关键字访问特点
 
static关键字修饰的成员(成员变量和成员函数)与类同时加载到内存,所以会早于普通的成员变量,并且加载到内存堆区的静态域中,所以,在调用时需要注意下面的情况:
-  非静态成员可以访问静态成员 package com.epsda.java_static;  /** * ClassName: java_static * Package: com.epsda.java_static * Description: * * @author 憨八嘎 * @version 1.0 */ public class java_static { public static void main(String[] args) { }  // 非静态成员 public void func1() { // 非静态成员可以直接访问静态成员 func2(); }  // 静态成员 public static void func2(){  } }
-  静态成员不可以访问非静态成员,除非创建对象,因为对象创建后,非静态成员也被创建了 package com.epsda.java_static;  /** * ClassName: java_static * Package: com.epsda.java_static * Description: * * @author 憨八嘎 * @version 1.0 */ public class java_static { public static void main(String[] args) { // func1(); 非静态成员不可以被静态成员直接调用 java_static js = new java_static(); js.func1();// 但是可以通过对象调用 }  // 非静态成员 public void func1() {  } }
-  非静态成员可以访问非静态成员,静态成员可以访问静态成员 
static成员在开发中一般可以指定一个工具类,工具类是指该类中是某一种对象的常见方法,该方法被修饰为static,便于使用类名直接调用。特殊地,工具类的构造方法全是private修饰
可变参数
在Java中,如果不确定函数参数的具体个数,可以使用可变参数进行代替,声明可变参数的方式如下
 数据类型...变量名例如,求出n个整数相加之和
 package com.epsda.multiple_variables;
 
 /**
  * ClassName: Multi_variables
  * Package: com.epsda.multiple_variables
  * Description:
  *
  * @author 憨八嘎
  * @version 1.0
  */
 public class Multi_variables {
     public static void main(String[] args) {
         int ans1 = sum(1,2,3);
         int ans2 = sum(1,2,3,4);
         int ans3 = sum(1,2,3,4,5);
         System.out.println("ans1 = " + ans1);
         System.out.println("ans2 = " + ans2);
         System.out.println("ans3 = " + ans3);
     }
 
     public static int sum(int...arr) {
         int ans = 0;
         for (int i = 0; i < arr.length; i++) {
             ans += arr[i];
         }
         return ans;
     }
 }
 
 输出结果:
 ans1 = 6
 ans2 = 10
 ans3 = 15在Java中,可变参数实际上是一个数组类型,所以可以使用数组的方式进行遍历
一个形参位置只能有一个可变参数,并且如果有其他参数时,可变参数必须放在最后一个参数的位置
package com.epsda.multiple_variables;
 
 /**
  * ClassName: Multi_variables
  * Package: com.epsda.multiple_variables
  * Description:
  *
  * @author 憨八嘎
  * @version 1.0
  */
 public class Multi_variables {
     public static void main(String[] args) {
         // 第一个实参给函数的一个形参,剩下的全给可变参数
         String ans = concat("-", "字符串1", "字符串2");
         System.out.println("ans = " + ans);
     }
     
     // 多个参数,可变参数放在最后
     public static String concat(String regex, String... arr) {
         String ans = "";
         for (int i = 0; i < arr.length; i++) {
             if (i == arr.length - 1) {
                 ans += arr[i];
             } else {
                 ans += arr[i] + regex;
             }
         }
 
         return ans;
     }
 }
 
 输出结果:
 ans = 字符串1-字符串2对象数组与传值/址调用
对象数组
所谓对象数组,即数组中的元素是对象
package com.epsda.array;
 
 /**
  * ClassName: object_array
  * Package: com.epsda.array
  * Description:
  *
  * @author 憨八嘎
  * @version 1.0
  */
 public class object_array {
     public static void main(String[] args) {
         // 创建对象数组
         Person arr[] = new Person[3];
         // 创建对象并存入数组中
         for (int i = 0; i < arr.length; i++) {
             // 数组中的每一个元素都是Person的匿名对象
             arr[i] = new Person(18,"姓名");
             System.out.println(arr[i].getName()+" "+arr[i].getAge());
         }
     }
 }传值调用与传址调用
在Java中,基本数据类型实参传递给方法的形参时只是传值调用,但是对于引用类型来说,传递给方法形参的实参都是地址,所以是传址调用
package com.epsda.call;
 
 /**
  * ClassName: Call
  * Package: com.epsda.call
  * Description:
  *
  * @author 憨八嘎
  * @version 1.0
  */
 public class Call {
     public static void main(String[] args) {
         // 基本数据类型
         int a = 10;
         int b = 20;
         sum(a, b);
         System.out.println("a = " + a);// 方法内修改不影响main函数中的a和b,传值调用
         System.out.println("b = " + b);
         System.out.println("---------------------------");
         // 引用数据类型
         int arr[] = {2, 3, 4, 5};
         change(arr, arr1);// 方法内的修改影响main函数中的引用类型
         for (int i = 0; i < arr.length; i++) {
             System.out.print(arr[i] + " ");
         }
     }
 
     // 传值调用
     public static void sum(int a, int b) {
         a = 20;
         b = 40;
         System.out.println("a = " + a);
         System.out.println("b = " + b);
     }
 
     // 传址调用
     public static void change(int[] arr, String arr1) {
         for (int i = 0; i < arr.length; i++) {
             arr[i] = i;
             System.out.print(arr[i] + " ");
         }
         System.out.println();
     }
 }
 
 输出结果:
 a = 20
 b = 40
 a = 10
 b = 20
 ---------------------------
 0 1 2 3
 0 1 2 3 需要注意的是
String类型引用,在Java中,字符串是不可改变的量,所以如果在方法内尝试对实参的String类型值进行改变并不会影响实参。每一个字符串都有对应的地址,当指向字符串的实参传入方法中,在方法内改变该实参对应的形参内容只是改变形参指向的地址值,并不会改变实参指向的地址值,本质这里还是传值调用,例如:package com.epsda.call;  /** * ClassName: Call * Package: com.epsda.call * Description: * * @author 憨八嘎 * @version 1.0 */ public class Call { public static void main(String[] args) { String arr1 = "字符串"; change(arr1);// 方法内的修改不影响main函数arr1 System.out.print(arr1); } public static void change(String arr1) { arr1 = "修改字符串"; System.out.print(arr1); System.out.println(); } }  输出结果: 修改字符串 字符串
命令行参数
Java中的main方法有一个形参String[] args,当需要临时测试方法时,可以通过这个形参传递值
 public class CommandParam{
     public static void main(String[] args){
         for(int i = 0; i < args.length; i++){
             System.out.println("第" + (i+1) + "个参数的值是:" + args[i]);
         }
     }
 }在命令行中输入命令:
 javac CommandParam.java
 java CommandParam 字符串1 字符串2此时即可输出下面的内容:




















