第四章----面向对象(上)

一、三大特征

①封装性

②继承性

③多态性

二、类和对象

①类是对一类事物的描述,是抽象的、概念上的定义

②对象是实际存在的该类事务的每个个体,也称为实例

③万事万物皆为对象

|-常见的类成员:

属性:对应类中的成员变量

行为:对应类中的成员方法
属性=成员变量=filed=域、字段

方法=成员变量=函数=method

创建类的队象=类的实例化=实例化类

例:类和对象的使用

package com.atguigu.java;
//测试类
public class PersonTest {
   public static void main(String[] args) {
        
        //创建Person的类对象
        Person p1 = new Person();
        
        //调用对象的结构:属性、方法
        //调用属性:"对象.属性"
        p1.name = "Tom";
        p1.isMale =true;
        System.out.println( p1.name );
        
        //调用方法:"对象.方法"
        p1.eat();
        p1.sleep();
        p1.talk("Chinese");
}
}
class Person{
     
     //属性
     String name;
     int age = 1;
     boolean isMale;
     
     //方法
     public void eat() {
         System.out.println("人可以吃饭");
     }
     
     public void sleep() {
         System.out.println("人可以睡觉");
     }
     public void talk(String language) {
         System.out.println("人可以说话" + language);
     }
}

④如果创建了一个类的多个对象,则每个对象都独立的拥有一套类的属性(非static的),如果修改一个对象的属性a,则不影响另外一个对象属性a的值
例:

package com.atguigu.java;
//测试类
public class PersonTest {
   public static void main(String[] args) {
        
        //创建Person的类对象
        Person p1 = new Person();

        //*********************************
        Person p2 = new Person();
        System.out.println(p2.name);
        System.out.println(p2.isMale);
        //**********************************
        //将p1变量保存的对象地址值付给p3,导致p1和p3指向了堆空间中的同一个对象实体
        Person p3 = p1;
        System.out.println(p3.name);
        
        p3.age = 10;
        System.out.println(p1.age);
}
   
}
class Person{
     
     //属性
     String name;
     int age = 1;
     boolean isMale;
     
     //方法
     public void eat() {
         System.out.println("人可以吃饭");
     }
     
     public void sleep() {
         System.out.println("人可以睡觉");
     }
     public void talk(String language) {
         System.out.println("人可以说话" + language);
     }
}

三、对象的内存解析

![cba395a988eab716251c66d56a4545e7.jpeg][cba395a988eab716251c66d56a4545e7]

在这里插入图片描述

四、属性与局部变量的对比

①属性(成员变量)& 局部变量

|-相同点:

定义变量的格式:数据类型 变量名 = 变量值

先声明,后使用

变量都有其对应的作用域

|-不同点:

①在类中声明的位置不同

属性:直接定义在类的一对{}内

局部变量:声明在方法内、方法形参、代码块内、构造形参、构造器内部的变量

②关于权限修饰符

属性:可以在声明属性时,指明其权限,使用权限修饰符

常用的权限修饰符:private、public、缺省、protected

局部变量:不可以使用权限修饰符

③默认初始化值的情况:

属性:类的属性,根据其类型,都有默认初始化值

           整型:(byte、short、int、long):0
           浮点型:(float、double):0.0
           字符型:(char):0(或、\u0000)
           布尔型:(boolean):false
           引用数据类型:null

局部变量:没有默认初始化值,所以在调用局部变量之前。一定要显式赋值

特别地:形参在调用时赋值即可

④在内存中加载的位置:

属性:加载到堆空间中(非static)

局部变量:加载到栈空间

例:

package com.atguigu.java;
public class UserTest {
public static void main(String[] args) {
     User u1 = new User();
     System.out.println(u1.name);
     System.out.println(u1.age);
     System.out.println(u1.isMale);
     
     u1.talk("日语");
     u1.eat();
     
}
}
class User{
     //属性(或成员变量)
     String name;
     int age;
     boolean isMale;
     public void talk(String language) {//language:形参
         System.out.println("我们使用" + language +"交流");
     }
     
     public void eat() {
         String food = "烙饼";//局部变量
         System.out.println("北方人喜欢吃:" + food);
     }
}

五、类中方法的声明和使用

方法:描述类应该具有的功能

比如:Math类、sqrt()、random()、

     scanner类

     Arrays类、sort()、binarySearch()、equals()

分类:按照是否有形参及返回值

![440070aca09a108e2a6a9cae763ce36c.png][440070aca09a108e2a6a9cae763ce36c]

声明:

权限修饰符 返回值类型 方法名 (形参列表){

                  方法体;

            }

说明:

①关于权限修饰符

private、public、缺省、protected

②返回值类型:有返回值&无返回值

1.如果方法有返回值,则必须在方法声明时,指定返回值的类型,同时方法中需要使用return关键字来指定类型的变量或常量

2.如果方法没有返回值,则声明方法时,使用void来表示,通常没有返回值的方法中就不需要使用return,如果使用的话,只能“return;”,表示结束此方法,return后不可以使用执行语句

3.该不该有返回值?

①题目要求

②凭经验,具体问题具体分析

方法名:

①属于标识符,遵循标识符的规则和规范,“见名知意”

形参列表:

①方法可以声明0、1个或多个形参

②格式:数据类型1 形参1,数据类型2 形参2…

③该不该定义形参?

1.题目要求

2.凭经验,具体问题具体分析

方法体:方法功能的体现。

例:

package com.atguigu.java;
public class CustomerTest {
}
//客户类
class Customer{
     
     //属性
     String name;
     int age;
     boolean isMale;
     
     //方法
     public void eat(){
         System.out.println("客户吃饭");
     }
     
     public void sleep(int hour) {
         System.out.println("休息了"+hour+"个小时");
     }
     
     public String getName() {
         return name;
     }
     
     public String getNation(String nation) {
         String info = "我的国籍是:"+ nation;
         return info;
     }
}

六、return关键字的使用

①使用范围:使用在方法体中

②作用:结束方法、针对于有返回值类型的方法,使用"return 数据" 方法返回所要的数据

③注意点:return关键字后面不可以声明执行语句

七、方法使用中的注意点:

①可以调用当前类的属性或方法

②特殊的:方法A中又调用了方法A:递归方法

③方法中,不可以定义方法

八、理解:万事万物皆对象

①在Java语言的范畴中,我们都将功能、结构等封装到类中,通过类的实例化,来调用具体的功能结构

|-Scanner,String等

|-文件:File

|-网络资源:URL

②涉及到Java语言与前端HTML交互时、后端的数据库交互时,前后端的结构在Java层面交互时,都体现为类、对象

九、对象数组内存解析

①引用类型的变量,只可能存储两类值:null或地址值(含变量类型)

例:

package com.guigu.exer;
public class StudentTest {
     public static void main(String[] args) {
         // 声明student的数组
         Student[] stus = new Student[20];
         for (int i = 0; i < stus.length; i++) {
              // 给数组元素赋值
              stus[i] = new Student();
              // 给student的属性赋值
              stus[i].number = (i + 1);
              // 年级【1-6】
              stus[i].state = (int) (Math.random() * (6  - 1 + 1) + 1);
              // 成绩【0-100】
              stus[i].score = (int) (Math.random() *  (100 - 0 + 1));
         }
         // 遍历学生数组
         for (int i = 0; i < stus.length; i++) {
              System.out.println(stus[i].info());
         }
         
         System.out.println("*********************");
         //冒泡排序按学生成绩排序,并遍历所有学生信息
         for (int i = 0; i < stus.length - 1; i++) {
              for (int j = 0; j < stus.length - 1 - i;  j++) {
                  if (stus[j].score > stus[j +  1].score) {
                       //如果交换顺序,交换的是数组元素
                       Student temp =stus[j];
                       stus[j] = stus[j + 1];
                       stus[j + 1] = temp;
                  }
              }
         }
         // 遍历学生数组
                       for (int i = 0; i < stus.length;  i++) {
                            System.out.println(stus[i].info());
                       }
                       
         
         //打印出三年级的学生信息
         for (int i = 0; i < stus.length; i++) {
              if (stus[i].state == 3) {
                  System.out.println(stus[i].info());
              }
         }
     }
     
}
class Student {
     int number;// 学号
     int state;// 年级
     int score;// 成绩
     
     //显式学生信息方法
     public String info() {
         return "学号:" + number +",年级" + state +  ",成绩:" + score;
     }
}

改进:

package com.guigu.exer;
/*
* 4. 对象数组题目:
定义类Student,包含三个属性:学号number(int),年级state(int),成绩score(int)。
创建20个学生对象,学号为1到20,年级和成绩都由随机数确定。
问题一:打印出3年级(state值为3)的学生信息。
问题二:使用冒泡排序按学生成绩排序,并遍历所有学生信息
提示:
1) 生成随机数:Math.random(),返回值类型double;  
2) 四舍五入取整:Math.round(double d),返回值类型long。
*
*
* 此代码是对StudentTest.java的改进:将操作数组的功能封装到方法中。
*
*/
public class StudentTest1 {
     public static void main(String[] args) {
         
         //声明Student类型的数组
         Student1[] stus = new Student1[20];  
         
         for(int i = 0;i < stus.length;i++){
              //给数组元素赋值
              stus[i] = new Student1();
              //给Student对象的属性赋值
              stus[i].number = (i + 1);
              //年级:[1,6]
              stus[i].state = (int)(Math.random() * (6  - 1 + 1) + 1);
              //成绩:[0,100]
              stus[i].score = (int)(Math.random() *  (100 - 0 + 1));
         }
         
         StudentTest1 test = new StudentTest1();
         
         //遍历学生数组
         test.print(stus);
         
         System.out.println("********************");
         
         //问题一:打印出3年级(state值为3)的学生信息。
         test.searchState(stus, 3);
         
         System.out.println("********************");
         
         //问题二:使用冒泡排序按学生成绩排序,并遍历所有学生信息
         test.sort(stus);
         
         //遍历学生数组
         test.print(stus);
         
     }
     
     /**
      *
      * @Description  遍历Student1[]数组的操作
      * @author shkstart
      * @date 2019年1月15日下午5:10:19
      * @param stus
      */
     public void print(Student1[] stus){
         for(int i = 0;i <stus.length;i++){
              System.out.println(stus[i].info());
         }
     }
     /**
      *
      * @Description 查找Stduent数组中指定年级的学生信息
      * @author shkstart
      * @param stus 要查找的数组
      * @param state 要找的年级
      */
     public void searchState(Student1[] stus,int  state){
         for(int i = 0;i <stus.length;i++){
              if(stus[i].state == state){
                  System.out.println(stus[i].info());
              }
         }
     }
     
     /**
      *
      * 
      * @date 2019年1月15日下午5:09:46
      * @param stus
      */
     public void sort(Student1[] stus){
         for(int i = 0;i < stus.length - 1;i++){
              for(int j = 0;j < stus.length - 1 -  i;j++){
                  if(stus[j].score > stus[j +  1].score){
                       //如果需要换序,交换的是数组的元素:Student对象!!!
                       Student1 temp = stus[j];
                       stus[j] = stus[j + 1];
                       stus[j + 1] = temp;
                  }
              }
         }
     }
     
     
}
class Student1{
     int number;//学号
     int state;//年级
     int score;//成绩
     
     //显示学生信息的方法
     public String info(){
         return "学号:" + number + ",年级:" + state +  ",成绩:" + score;
     }
}

![626f6716fa7ad29ff7e1d32c2e73e8f7.png][626f6716fa7ad29ff7e1d32c2e73e8f7]

十、匿名对象的使用

①理解:创建的对象,没有显示的赋给一个变量名,即为匿名对象

②特征:匿名对象只能调用一次

③使用:

例:匿名对象的使用

package com.atguigu.java;
public class InstanceTest {
     public static void main(String[] args) {
         Phone p = new Phone();
         
         System.out.println(p);
         
         p.sedEmail();
         p.playGame();
         
         //匿名对象
//       new Phone().sedEmail();
//       new Phone().playGame();
         
         new Phone().price = 2000;
         new Phone().showPrice();
         
         //***************************
         PhoneMall mall =new PhoneMall();
         //匿名对象的使用
         mall.show(new Phone());
     }
     
     
}
class PhoneMall{
     public void show(Phone phone) {
         phone.sedEmail();
         phone.playGame();
     }
}
class Phone {
     double price;
     
     public void sedEmail() {
         System.out.println("发送邮件");
     }
     
     public void playGame() {
         System.out.println("玩游戏");
     }
     public void showPrice() {
         System.out.println("手机价格为:" + price);
     }
}

十一、自定义数组的工具类

例:数组的工具类

package com.atguigu.java;
public class ArrayUtil {
     // 求数组的最大值
     public int getMax(int[] arr) {
         int maxValue = arr[0];
         for (int i = 0; i < arr.length; i++) {
              if (maxValue < arr[i]) {
                  maxValue = arr[i];
              }
         }
         return maxValue;
     }
     // 求数组的最小值
     public int getMin(int[] arr) {
         int minValue = arr[0];
         for (int i = 0; i < arr.length; i++) {
              if (minValue > arr[i]) {
                  minValue = arr[i];
              }
         }
         return minValue;
     }
     // 求数组的总和
     public int getSum(int[] arr) {
         int sum = 0;
         for (int i = 0; i < arr.length; i++) {
              sum += arr[i];
         }
         return sum;
     }
     // 求数组的平均值
     public int getAvg(int[] arr) {
         return getSum(arr) / arr.length;
     }
     // 反转数组
     public void reverse(int[] arr) {
         for (int i = 0; i < arr.length / 2; i++) {
              int temp = arr[i];
              arr[i] = arr[arr.length - i - 1];
              arr[arr.length - i - 1] = temp;
         }
     }
     // 复制数组
     public int[] copy(int[] arr) {
         int[] arr1 = new int[arr.length];
         for (int i = 0; i < arr1.length; i++) {
              arr1[i] = arr[i];
         }
         return arr1;
     }
     // 数组排序
     public void sort(int[] arr) {
         for (int i = 0; i < arr.length - 1; i++) {
              for (int j = 0; j < arr.length - 1 - i;  j++) {
                  if (arr[j] > arr[j + 1]) {
                       int temp = arr[j];
                       arr[j] = arr[j + 1];
                       arr[j + 1] = temp;
                  }
              }
         }
         for (int i = 0; i < arr.length; i++) {
              System.out.print(arr[i] + "\t");
         }
     }
     // 遍历数组
     public void print(int[] arr) {
         for (int i = 0; i < arr.length; i++) {
              System.out.print(arr[i] + " \t");
         }
         System.out.println();
     }
     // 查找指定元素
     public int getIndex(int[] arr, int dest) {
         for (int i = 0; i < arr.length; i++) {
              if (dest == (arr[i])) {
                  return i;
              }
         }
         return -1;// 返回一个复数,表示没找到
     }
}

测试类:

package com.atguigu.java;
public class ArrayUtilTest {
     public static void main(String[] args) {
         ArrayUtil util = new ArrayUtil();
         int[] arr = new int[] { 2, 5, 6, 8, 10, 12,  13, 6 };
         int max = util.getMax(arr);
         System.out.println("最大值为:" + max);
         System.out.println("排序前:");
         util.print(arr);
         System.out.println();
         System.out.println("排序后:");
         util.sort(arr);
         
         
         System.out.println();
         System.out.println("查找:");
         int index = util.getIndex(arr, 6);
         if (index > 0) {
              System.out.println("找到了,索引地址为:" +  index);
         } else {
              System.out.println("未找到!");
         }
     }
}

十二、理解方法的重载

①概念:在同一个类中,允许存在一个以上的同名方法,只要他们的参数个数或者参数类型不同即可

|-“两同一不同”:同一个类,相同方法名;参数列表不同,参数个数不同,参数类型不同

|-判断是否是重载:跟方法的权限修饰符、返回值类型、形参变量名、方法体都没关系

|-在通过对象调用方法时,如何确定某一个指定的方法:

方法名—>参数列表

例:

package com.atguigu.java;
public class OverLoadTest {
     public void getSum(int i, int j) {
         System.out.println(i + j);
     }
     public void getSum(double d1, double d2) {
     }
     public void getSum(String s, int i) {
     }
     public void getSum(int i, String s) {
     }
}

例:

package com.atguigu.exer;
public class OverloadExer {
     public void mOL(int i) {
         System.out.println(i * i);
     }
     public void mOL(int i, int j) {
         System.out.println(i * j);
     }
     public void mOL(String s) {
         System.out.println(s);
     }
     // ------------------------------------------
     public int max(int i, int j) {
         return (i > j) ? i : j;
     }
     public double max(double d1, double d2) {
         return (d1 > d2) ? d1 : d2;
     }
     public double max(double d1, double d2, double d3)  {
         double max = (d1 > d2) ? d1 : d2;
         return (max > d3) ? max : d3;
     }
}

十三、可变个数的形参

①Varargs(variable number of argments)机制,允许直接定义能和多个是实参匹配的形参

|-格式:数据类型  ... 变量名

|-当调用可变个数形参方法时,传入的参数个数可以是:0个,1个,2个.........

|-可变个数形参的方法与本类中方法名相同,形参不同的方法名之间构成重载

|-可变个数形参的方法与本类中方法名相同,形参类型也相同的数组之间不构成重载,二者不能共存

|-可变个数形参在方法的形参中必须声明在末尾

|-可变个数形参在方法的形参中,最多只能声明一个可变形参

例:

package com.atguigu.exer;
public class MethodArgsTest {
     public static void main(String[] args) {
         MethodArgsTest test = new MethodArgsTest();
         test.show(12);
         test.show("hell");
         test.show("aa", "bb", "cc");
     }
     public void show(int i) {
     }
     public void show(String s) {
         System.out.println("show(String)");
     }
     public void show(String... strs) {// 可变个数的形参
         System.out.println("show(String ... strs)");
         for (int i = 0; i < strs.length; i++) {
              System.out.println(strs[i]);
         }
     }
     // 可变个数形参在方法的形参中必须声明在末尾
     public void show(int i, String... strs) {
     }
}

十四、理解变量的赋值

①如果变量是基本数据类型,此时赋值的是变量所保存的数据值

②如果变量是引用数据类型,此时赋值的是变量所保存的数据的地址值

例:

package com.atguigu.java;
public class ValueTransferTest {
     public static void main(String[] args) {
         System.out.println("************基本数据类型:**************");
         int m = 10;
         int n = m;
         System.out.println("m = " + m + " , n =" + n);
         n = 20;
         System.out.println("m = " + m + " , n =" + n);
         System.out.println("************引用数据类型:**************");
         Oreder o1 = new Oreder();
         o1.orderId = 1001;
         Oreder o2 = o1;// 赋值以后,o1和o2的地址值相同,都指向了堆空间中同一个对象实体
         System.out.println("o1.orderId " + o1.orderId  + ",o2.orderId=" + o2.orderId);
         o2.orderId = 1002;
         System.out.println("o1.orderId " + o1.orderId  + ",o2.orderId=" + o2.orderId);
     }
}
class Oreder {
     int orderId;
}

十五、值传递机制

1.针对基本数据类型:

|-形参:方法定义时,声明的小括号内的参数

|-实参:方法调用时,实际春递给形参的数据

①值传递机制:

|-如果参数是基本数据类型,此时实参赋给形参的是,实参真实存储的数据值

|-如果参数是引用数据类型,此时实参赋给形参的是实参存储数据的地址值

例:

package com.atguigu.java;
public class ValueTransferTest2 {
     public static void main(String[] args) {
         Data data = new Data();
         data.m = 10;
         data.n = 20;
         System.out.println("m = " + data.m + ", n = "  + data.n);
         // 交换m和n的值
//       int temp = data.m;
//       data.m = data.n;
//       data.n = temp;
         ValueTransferTest2 test = new  ValueTransferTest2();
         test.swap(data);
         System.out.println("m = " + data.m + ", n = "  + data.n);
     }
     public void swap(Data data) {
         int temp = data.m;
         data.m = data.n;
         data.n = temp;
     }
}
class Data {
     int m;
     int n;
}
public void sort(int[] arr) {
         for (int i = 0; i < arr.length - 1; i++) {
              for (int j = 0; j < arr.length - 1 - i;  j++) {
                  if (arr[j] > arr[j + 1]) {
//                     int temp = arr[j];
//                     arr[j] = arr[j + 1];
//                     arr[j + 1] = temp;
                       // swap(arr[j], arr[j + 1]);
                       swap(arr, j, j + 1);
                  }
              }
         }
         for (int i = 0; i < arr.length; i++) {
              System.out.print(arr[i] + "\t");
         }
     }
     // 交换数组中指定两个位置元素的值
     public void swap(int[] arr, int i, int j) {
         int temp = arr[i];
         arr[i] = arr[j];
         arr[j] = temp;
     }

②参数传递的编码练习

例:将对象作为参数传递给方法

package com.atguigu.exer;
public class PassObject {
     public static void main(String[] args) {
         PassObject test = new PassObject();
         Circle c = new Circle();
         test.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;
              double area = c.findArea();
              System.out.println(c.radius + "\t\t" +  area);
              // System.out.println(c.radius + "\t\t" +  c.findArea());
         }
         c.radius = time + 1;
     }
}

十六、递归(Recrusion)方法的使用

①递归方法:一个方法体内调用它自身

|-方法递归包含了一种隐式的循环,它会重复执行某段代码,但这种重复执行无须循环控制

|-递归一定要向已知方向递归,否则这种递归就变成无穷递归,类似于死循环

例:

package com.atguigu.java;
public class RecrusionTest {
     public static void main(String[] args) {
         // 计算1-n之间所有自然数的和
         // 方式一:
         int sum = 0;
         for (int i = 0; i <= 100; i++) {
              sum += i;
         }
         System.out.println(sum);
         // 方式二:使用递归实现
         RecrusionTest test = new RecrusionTest();
         int sum1 = test.getsum(100);
         System.out.println(sum1);
         System.out.println("****************");
         int value = test.f(10);
         System.out.println(value);
     }
     public int getsum(int n) {
         if (n == 1) {
              return 1;
         } else {
              return n + getsum(n - 1);
         }
     }
     // 计算1-n之间所有自然数的乘积
     public int getsum1(int n) {
         if (n == 1) {
              return 1;
         } else {
              return n * getsum1(n - 1);
         }
     }
     // 求f(10)的值
     public int f(int n) {
         if (n == 0) {
              return 1;
         } else if (n == 1) {
              return 4;
         } else {
              return 2 * f(n - 1) + f(n - 2);
         }
     }
}

十七、封装与隐藏

①高内聚:类的内部数据操作细节自己完成,不允许外部干涉

低耦合:仅对外暴露少量的方法用于使用

②创建一个对象之后,我们可以通过“对象.属性”的方式,对对象的属性进行赋值。赋值操作要受到属性的数据类型和存储范围的制约,但是除此之外没有其他制约条件,在实际问题中,我们往往需要给属性赋值加入额外限制条件,这个条件就不能在属性声明时体现,只能通过方法进行限制条件的添加,同时需要避免用户再使用“对象.属性”的方式对属性进行赋值,则需要将属性声明为私有的(private),此时就体现了封装性。

例:

package com.atguigu.java;
public class AimalTest {
    public static void main(String[] args) {
         Animal a = new Animal();
         a.name = "花花";
         a.age = 1;
         a.legs = 4;
         a.show();
         a.setlegs(6);
         a.show();
    }
}
class Animal {
    String name;
    int age;
    int legs;// 腿的个数
    public void setlegs(int l) {
         if (l >= 0 && l % 2 == 0) {
             legs = l;
         } else {
             legs = 0;
         }
    }
    public void eat() {
         System.out.println("动物进食");
    }
    public void show() {
         System.out.println("name = " + name +  ",age = " + age + ",legs =" + legs);
    }
}

③封装性的体现:

将类的属性xxx私有化(private),同时提供公共的(public)方法来获取(get xxx)和设置(set xxx)此属性的值

拓展:

|-不对外暴露的私有的方法

|-单例模式

例:

package com.atguigu.java;
public class AimalTest {
    public static void main(String[] args) {
         Animal a = new Animal();
         a.name = "花花";
         // a.age = 1;
         // a.legs = 4;
         a.show();
         a.setlegs(6);
         a.show();
    }
}
class Animal {
    String name;
    private int age;
    private int legs;// 腿的个数
    // 对属性的设置
    public void setlegs(int l) {
         if (l >= 0 && l % 2 == 0) {
             legs = l;
         } else {
             legs = 0;
         }
    }
    // 对属性的获取
    public int getLegs() {
         return legs;
    }
    public void eat() {
         System.out.println("动物进食");
    }
    public void show() {
         System.out.println("name = " + name +  ",age = " + age + ",legs =" + legs);
    }
    // 提供关于属性age的get和set方法
    public int getAge() {
         return age;
    }
    public void setAge(int a) {
         age = a;
    }
}

④封装性的体现需要权限修饰符来配合

|-4种权限:private、default(缺省)、protected、public

|-都可以修饰类及类的内部结构:属性、方法、构造器、内部类

|-都可以修饰类的内部结构:属性、方法、构造器、内部类

|-修饰类只能使用:default(缺省)、public

![0d58480b27eb203af0167d53a4e8369f.png][0d58480b27eb203af0167d53a4e8369f]![48403ede354cd74869db088155ffceef.png][48403ede354cd74869db088155ffceef]在这里插入图片描述

例:

package com.atguigu.java;
public class Order {
    private int orderPrivate;
    int orderDefault;
    public int orderPublic;
    private void methodPrivate() {
         orderPrivate = 1;
         orderDefault = 2;
         orderPublic = 3;
    }
    void methodDefault() {
         orderPrivate = 1;
         orderDefault = 2;
         orderPublic = 3;
    }
    public void methodPublic() {
         orderPrivate = 1;
         orderDefault = 2;
         orderPublic = 3;
    }
}
package com.atguigu.java;
public class OrderTest {
    public static void main(String[] args) {
         Order order = new Order();
         order.orderDefault = 1;
         order.orderPublic = 2;
         // 出了Order类之后,私有的结构就不可以调用了
         //order.orderPrivate = 3; // The field  Order.orderPrivate is not visible
         
         order.methodDefault();
         order.methodPublic();\
         // 出了Order类之后,私有的结构就不可以调用了
         //order.methPrivate();//The method  methPrivate() is undefined for the type Order
    }
}
package com.atguigu.java1;
import com.atguigu.java.Order;
public class OrderTest {
public static void main(String[] args) {
    Order order = new Order();
    // 出了Order类所属的包之后,私有的结构、缺省声明的结构就不可以调用了
    //order.orderDefault = 1;
    order.orderPublic = 2;
    // 出了Order类之后,私有的结构就不可以调用了
    //order.orderPrivate = 3; // The field  Order.orderPrivate is not visible
    
    // 出了Order类所属的包之后,私有的结构、缺省声明的结构就不可以调用了
    //order.methodDefault();
    order.methodPublic();
    // 出了Order类之后,私有的结构就不可以调用了
    //order.methPrivate();//The method  methPrivate() is undefined for the type Order
}
}

总结:

Java提供了四种权限修饰符来修饰类及类的内部结构,体现类及类的内部结构在被调用时的可见性的大小

例:

package com.atguigu.exer;
public class Person {
    private int age;
    public void setAge(int a) {
         if (a < 0 || a > 130) {
             System.out.println("传入的数据非法!");
             return;
         }
         age = a;
    }
    public int getAge() {
         return age;
    }
//绝对不要这样写
//  public int dogAge(int a) {
//       age = a;
//       return age;
//  }
}
package com.atguigu.exer;
public class PersonTest {
    public static void main(String[] args) {
         Person p1 = new Person();
         p1.setAge(12);
         System.out.println("年龄为:" +  p1.getAge());
    }
}

十八、构造器(构造方法)constructor:建设者

①:作用

|-创建对象

|-初始化对象的信息

②:说明

|-如果没有显式的定义类的构造器的话,则系统默认提供一个空参的构造器

|-定义构造器的格式:权限修饰符 类名(形参列表){}

|-一个类中定义的构造器,彼此构成重载

|-一旦显式的定义了类的构造器之后,系统不再提供默认的空参构造器

|-一个类中,至少会有一个构造器

例:

package com.atguigu.java1;
public class PersonTest {
    public static void main(String[] args) {
         // 创建类的对象:new+构造器
         Person p = new Person();
         p.eat();
         Person p1 = new Person("Tom");
         System.out.println(p1.name);
    }
}
class Person {
    // 属性
    String name;
    int age;
    // 构造器
    public Person() {
         System.out.println("Person()........");
    }
    public Person(String n) {
         name = n;
    }
    public Person(String n, int a) {
         name = n;
         age = a;
    }
    // 方法
    public void eat() {
         System.out.println("人吃饭!");
    }
    public void study() {
         System.out.println("人可以学习!");
    }
}

例:

package com.atguigu.exer;
public class Person {
    private int age;
    private String name;
    public Person() {
         age = 18;
    }
    public Person(String n, int a) {
         name = n;
         age = a;
    }
    public void setAge(int a) {
         if (a < 0 || a > 130) {
             System.out.println("传入的数据非法!");
             return;
         }
         age = a;
    }
    public int getAge() {
         return age;
    }
    public void setName(String n) {
         name = n;
    }
    public String getNanme() {
         return name;
    }
}
package com.atguigu.exer;
public class PersonTest {
    public static void main(String[] args) {
         Person p1 = new Person();
         // p1.setAge(12);
         System.out.println("年龄为:" +  p1.getAge());
         Person p2 = new Person("Tom", 21);
         System.out.println("name = " +  p2.getNanme() + ",age:" + p2.getAge());
    }
}

例:

package com.atguigu.exer1;
public class TriAngle {
    private double base;// 底边长
    private double height;// 高
    public TriAngle() {
    }
    public TriAngle(double b, double h) {
         base = b;
         height = h;
    }
    public void setBase(double b) {
         base = b;
    }
    public double getBase() {
         return base;
    }
    public void setHeight(double h) {
         height = h;
    }
    public double getHeight() {
         return height;
    }
}
package com.atguigu.java1;
import com.atguigu.exer1.TriAngle;
public class PersonTest {
    public static void main(String[] args) {
         TriAngle t1 = new TriAngle();
         t1.setBase(2.0);
         t1.setHeight(2.4);
         System.out.println("base:" + t1.getBase()  + ",height:" + t1.getHeight());
         
         TriAngle t2 = new TriAngle(5.1,5.6);
         System.out.println("base:" + t2.getBase()  + ",height:" + t2.getHeight());
    }
}

总结:

属性赋值的先后顺序:

①默认初始化值

②显式初始化

③构造器中赋值

④通过"对象.方法"或“对象.属性”

以上操作顺序: ①-②-③-④

例:

package com.atguigu.java1;
public class UserTest {
    public static void main(String[] args) {
         User u = new User();
         System.out.println(u.age);
         User u1 = new User(2);
         u1.setAge(3);
         System.out.println(u1.age);
    }
}
class User {
    String name;
    int age = 1;
    public User() {
    }
    public User(int a) {
         age = a;
    }
    public void setAge(int a) {
         age = a;
    }
}

十九、拓展

JavaBean的使用:

①:是一种Java语言写成的可重用组件

②:是指符合以下标准的Java类:

|-类是公共的

|-有一个无参的公共的构造器

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

例:

package com.atguigu.java1;
public class Customer {
    private int id;
    private String name;
    public Customer() {
    }
    public void setId(int i) {
         id = i;
    }
    public int getId() {
         return id;
    }
    public void setName(String n) {
         name = n;
    }
    public String getName() {
         return name;
    }
}

UML类图:
在这里插入图片描述

二十、关键字:this的使用

①this可以用来修饰、调用:属性、方法、构造器

②this修饰属性和方法 :

|-this理解为:当前对象 或  当前正在创建的对象

|-在类的方法中,可以使用“this.属性”或“this.方法”的方式,调用当前对象的属性或方法,但是通常情况下,都选择省略“this.”。特殊情 况下,如果的方法的形参和类的属性同名时,我们必须显式的使用”this.变量“的方式,表明此变量是属性,而非形参

|-在类的构造器中,可以使用“this.属性”或“this.方法”的方式,调用当前正在创建的对象的属性或方法,但是通常情况下,都选择省 略“this.”。特殊情况下,如果的方法的形参和类的属性同名时,我们必须显式的使用”this.变量“的方式,表明此变量是属性,而非形参

③this调用构造器:

|-在类的构造器中,可以显式的使用“this(形参列表)”方式,调用本类中指定的的其他构造器
|-构造器中不能通过“this(形参列表)”方式调用自己
|-如果一个类中有n个构造器,则最多有n - 1构造器使用了“this(形参列表)”
|-规定:“this(形参列表)”必须声明在当前构造器的首行
|-构造器内部,最多最多只能声明一个“this(形参列表)”,用来调用其他的构造器

例:

package com.atguigu.java2;
public class PersonTest {
    public static void main(String[] args) {
         Person p1 = new Person();
         p1.setAge(1);
         System.out.println(p1.getAge());
         p1.eat();
         System.out.println();
         Person p2 = new Person("Jerry", 20);
         System.out.println(p2.getAge());
    }
}
class Person {
    private String name;
    private int age;
    public Person() {
         this.eat();
         String info = "Person初始化时需要考虑40行代码";
         System.out.println(info);
    }
    public Person(String name) {
         this();
         this.name = name;
    }
    public Person(int age) {
         this();
         this.age = age;
    }
    public Person(String name, int age) {
         this(age);
         this.name = name;
         this.age = age;
    }
    public void setName(String name) {
         this.name = name;
    }
    public String getName() {
         return this.name;
    }
    public void setAge(int age) {
         this.age = age;
    }
    public int getAge() {
         return this.age;
    }
    public void eat() {
         System.out.println("人吃饭!");
         this.study();
    }
    public void study() {
         System.out.println("人学习!");
    }
}

④练习:

例一:

package com.atguigu.exer2;
public class Boy {
    private String name;
    private int age;
    public Boy() {
    }
    public Boy(String name) {
         this.name = name;
    }
    public Boy(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 void marry(Girl girl) {
         System.out.println("我想娶:" +  girl.getName());
    }
    public void shout() {
         if (this.age >= 22) {
             System.out.println("可以合法登记!");
         } else {
             System.out.println("先多谈谈恋爱!");
         }
    }
}
package com.atguigu.exer2;
public class Girl {
    private String name;
    private int age;
    public Girl() {
    }
    public Girl(String name, int age) {
         this.name = name;
         this.age = age;
    }
    public String getName() {
         return name;
    }
    public void setName(String name) {
         this.name = name;
    }
    public void marry(Boy boy) {
         System.out.println("我想嫁给:" +  boy.getName());
         boy.marry(this);
    }
    public int compare(Girl girl) {
         // if (this.age > girl.age) {
//           return 1;
//       } else if (this.age < girl.age) {
//           return -1;
//
//       } else {
//           return 0;
//       }
//  }
         return this.age - girl.age;
    }
}
package com.atguigu.exer2;
public class BoyGirlTest {
    public static void main(String[] args) {
         Boy boy = new Boy("罗密欧", 21);
         boy.shout();
         Girl girl = new Girl("朱丽叶", 18);
         girl.marry(boy);
         Girl girl1 = new Girl("祝英台", 19);
         int comapre = girl.compare(girl1);
         System.out.println(comapre);
         if (comapre > 0) {
             System.out.println(girl.getName() +  "大");
         } else if (comapre < 0) {
             System.out.println(girl1.getName() +  "大");
         } else {
             System.out.println("一样大");
         }
    }
}

例二:

package com.atguigu.exer3;
public class Account {
    private int id;// 账号
    private double blance;// 余额
    private double annualInterestRate;// 年利率
    public Account(int id, double blance, double  annualInterestRate) {
         this.id = id;
         this.blance = blance;
         this.annualInterestRate =  annualInterestRate;
    }
    public int getId() {
         return id;
    }
    public void setId(int id) {
         this.id = id;
    }
    public double getBlance() {
         return blance;
    }
    public void setBlance(double blance) {
         this.blance = blance;
    }
    public double getAnnualInterestRate() {
         return annualInterestRate;
    }
    public void setAnnualInterestRate(double  annualInterestRate) {
         this.annualInterestRate =  annualInterestRate;
    }
    // 判断用户余额是否能够满足取款需求
    public void withdraw(double amount) {// 取钱
         if (blance < amount) {
             System.out.println("余额不足,取款失败!");
             return;
         }
         blance -= amount;
         System.out.println("成功取出:" + amount);
    }
    public void deposit(double amount) {// 存钱
         if (amount > 0) {
             blance += amount;
             System.out.println("成功存入:" +  amount);
         }
    }
}
package com.atguigu.exer3;
public class Customer {
    private String firstName;
    private String lastAName;
    private Account account;
    public Customer(String f, String l) {
         this.firstName = f;
         this.lastAName = l;
    }
    public Account getAccount() {
         return account;
    }
    public void setAccount(Account account) {
         this.account = account;
    }
    public String getFirstName() {
         return firstName;
    }
    public String getLastAName() {
         return lastAName;
    }
}
package com.atguigu.exer3;
public class CustomerTest {
    public static void main(String[] args) {
         Customer cust = new Customer("Jane",  "Smith");
         Account acct = new Account(1000, 2000,  0.0123);
         cust.setAccount(acct);
         cust.getAccount().deposit(100);
         cust.getAccount().withdraw(960);
         cust.getAccount().withdraw(2000);
         System.out.println("Customer[" +  cust.getLastAName() + "," + cust.getFirstName() +  "] has a account: id is  "
                 + cust.getAccount().getId() +  ",annualInterestRate is" +  cust.getAccount().getAnnualInterestRate() * 100
                 + "% ,balance is " +  cust.getAccount().getBlance());
    }
}

例三:

package com.atguigu.exer4;
public class Account {
    private double balance;
    public Account(double init_balance) {
         this.balance = init_balance;
    }
    public double getBalance() {
         return balance;
    }
    // 存钱
    public void deposit(double amt) {
         if (amt > 0) {
             balance += amt;
             System.out.println("存钱成功!");
         }
    }
//取钱操作
    public void withdraw(double amt) {
         if (balance >= amt) {
             balance -= amt;
             System.out.println("取钱成功!");
         } else {
             System.out.println("取钱失败!");
         }
    }
}
package com.atguigu.exer4;
public class Customer {
    private String firstName;
    private String lastName;
    private Account account;
    public Customer(String f, String l) {
         this.firstName = f;
         this.lastName = l;
    }
    public Account getAccount() {
         return account;
    }
    public void setAccount(Account account) {
         this.account = account;
    }
    public String getFirstName() {
         return firstName;
    }
    public String getLastName() {
         return lastName;
    }
}
package com.atguigu.exer4;
public class Bank {
    private Customer[] customers;// 存放多个客户的数组
    private int numberOfCustomers;// 记录客户的个数
    public Bank() {
         customers = new Customer[10];
    }
//添加客户
    public void addCustomer(String f, String l) {
         Customer cust = new Customer(f, l);
         // customers[numberOfCustomers] = cust;
         // numberOfCustomers++;
         customers[numberOfCustomers++] = cust;
    }
//获取客户的个数
    public int getNumOfCustomers() {
         return numberOfCustomers;
    }
//获取指定位置上的客户
    public Customer getCustomer(int index) {
         // return customers[index];
         if (index >= 0 && index <  numberOfCustomers) {
             return customers[index];
         }
         return null;
    }
}
package com.atguigu.exer4;
public class BankTest {
    public static void main(String[] args) {
         Bank bank = new Bank();
         bank.addCustomer("Jane", "Smith");
         bank.getCustomer(0).setAccount(new  Account(2000));
         bank.getCustomer(0).getAccount().withdraw(500);
         double balance =  bank.getCustomer(0).getAccount().getBalance();
         System.out.println("客户:" +  bank.getCustomer(0).getFirstName() + "的账户余额为:" + balance);
         System.out.println("***************");
         bank.addCustomer("万里", "杨");
         System.out.println("银行客户的个数为:" +  bank.getNumOfCustomers());
    }
}

二十一、关键字:package、import的使用

①package关键字的使用:

|-为了更好的实现项目中类的管理,提供包的概念

|-使用package声明类或接口所属的包,声明在源文件的首行

|-包属于标识符,遵循标识符的命名规则、规范(xxxyyyzzz)、“见名知意”

|-每“.”一次,就代表一层文件目录

|-同一个包下,不能命名同名的接口、类,不同包下,不能命名同名的接口、类

![dc24d4675e3439e439c1959b97154963.png][dc24d4675e3439e439c1959b97154963]

②MVC设计模式:
在这里插入图片描述在这里插入图片描述
③import关键字的使用:

|-导入

|-在源文件中使用import结构导入指定包下的类、接口

|-声明在包的声明和类的声明之间

|-如果需要导入多个结构,则并列写出即可

|-可以使用“xxx.\*”的方式,表示可以导入“xxx”包下的所有结构

|-如果使用的类或接口是java.lang包下定义的,则可以省略import结构

|-如果使用的类是本包下定义的,则可以省略import结构

|-在源文件中,使用了不同包下的同名的类,则必须至少有一个类需要以全类名的方式显式

|-使用“xxx.\*”方式表明可以调用xxx包下的所有结构。但是如果使用的是xxx子包下的结构,则仍需要显式导入

|-import static :导入指定类或接口中的静态结构 :属性、方法

例:

package com.atguigu.java2;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Scanner;
import com.atguigu.exer3.Account;
import com.atguigu.exer4.Bank;
import com.atguigu.java2.java3.Dog;
import static java.lang.System.*;
import static java.lang.Math.*;
public class PackageImportTest {
    public static void main(String[] args) {
         String info = Arrays.toString(new int[] {  1, 2, 3 });
         Bank bank = new Bank();
         ArrayList list = new ArrayList();
         HashMap map = new HashMap();
         Scanner scanner = null;
         System.out.println("Hello!");
         Person person = new Person();
         Account acct = new Account(1000, 0, 0);
         // 以全类名的方式显示
         com.atguigu.exer3.Account acct1 = new  com.atguigu.exer3.Account(1000, 2000, 0.0123);
         Dog dog = new Dog();
         Field field = null;
         long num = Math.round(123.434);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值