JAVA基础篇(二)-------数组方法 + 面向对象 +好好看 好好学

JAVA 数组 + 面向对象

一、数组

1. 数组的基本使用

  • 数组的概念: 数组就是用来同时存储多个同类型元素的容器

    • JAVA : [1,2,3,4,5] JAVA 是强类型语言, 不能存储其他类型的数据, 要整型都是整型 ;要字符串 都是字符串。
    • python [1,2,“curry”,“james”] python 的list列表可以同时存储多个类型的数据。
    • 后面会整理一些 数据结构和算法 的文章 后期会发布 大家可以看看。
  • 格式:

    • 动态初始化: 我们指定长度,由系统给出默认值。
- 格式一: 数据类型[] 数组名 = new 数据类型[长度]**要求掌握**
	-      int  []  arr  = new   int   [3];
	- 堆区:[0,0,0]

- 格式二:数据类型 数组名 [] = new 数据类型[长度];
	-      int    arr  [] = new   int  [3];
	- 堆区: [0,0,0]
  • 静态初始化: 我们给出初始化值,由系统决定长度。
- 格式一: 数据类型 [] 数组名 = new 数据类型[] {1,值2,值3.......};
	-       int   []  arr  = new  int   [] {11,22,33,44 ......};
	- 堆区:  [11,22,33,44,55]
- 格式二: 数据类型 [] 数组名 = {1,值2,值3.......}**要求掌握   语法糖**
	-		int   []  arr  =  {11,22,33,44 .....};
	-	堆区:[11,22,33,44,55]
  • 格式解释

    • 例如: int[] arr = new int[3];
     	int   数据类型, 表示数组中能存储什么类型的元素.
    	[]    表示它是一个数组.
    	arr   表示数组名, 其实就是一个变量名.
    	new   表示去堆内存申请开辟空间.
    	3     表示数组的长度, 说明数组中最多只能存储3个整数.
    
  • 特点:

    • 数组中每个元素都是有下标的,默认从0开始
    • 数组中每个元素都是有默认值的。
      • 例如:int -> 0,double ->0.0,boolean -> false,String -> null
  • 案例: 数组入门

      1. 创建int类型的数组, 用来存储3个元素。
      1. 创建int类型的数组,存储数据11,22,33。
  • 代码

package demo01_array;
/*
    数组入门
    1. 创建 int类型的数组 用来存储3个元素
    2. 创建 int类型的数组 用来存储 11,22,33
 */
public class Demo01 {
    public static void main(String[] args) {
        // 创建动态类型数组
        // 语法1:数据类型[] 变量名称 = new 数据类型[数组长度]; [掌握]
        int [] arr = new int[3];
        // 语法2:数据类型 变量名称[] = new 数据类型[数组长度];
        int arr1 [] = new int[3];

        // 创建静态类型数组
        // 语法1:数据类型[] 变量名称 = new 数据类型[]{数据值,.....}
        int [] arr2 = new int[]{11,22,33};
        // 语法2:数据类型[] 变量名称 = {数据值,.....}  掌握 语法糖
        int [] arr3 = {11,22,33};
    }
}

2.数组的基本操作.

  • 数组的基本格式如下:
数组的基本格式如下:

- 数组名[索引]             根据索引, 获取该值.
- 数组名[索引] =;       根据索引, 修改该位置的值.
- 数组名.length           获取数组的长度  [11, 22, 33]       长度3
- 数组名.length - 1       获取数组的最大索    [11, 22, 33]      最大索引:2
  • 代码演示
package demo01_array;
/*
    数组的基本操作
 */
public class Demo02 {
    public static void main(String[] args) {
        // 定义数组 默认值[0,0,0]
        int [] arr = new int[3];
        // 打印数组的元素值
        System.out.println(arr[2]); // 0
        System.out.println("----------------[华丽分割线]----------------");

        // 修改数组元素值
        arr[2] = 10;
        System.out.println(arr[2]); // 10
        System.out.println("----------------[华丽分割线]----------------");

        //打印数组长度
        System.out.println(arr.length); // 3
        System.out.println("----------------[华丽分割线]----------------");

        // 打印数组最大索引值
        System.out.println(arr.length - 1); // 2
    }
}

3. 理解 数组的内存图

数组的内存图

public class Demo03 {
 //main方法也叫主方法(主函数), 所有的代码都是从这里开始执行的.
    public static void main(String[] args) {
        int[] arr = new int[3]; //0,0,0
        System.out.println(arr[0]);	//0
     		System.out.println(arr);    //地址值
    }
}

4. 数组时可能会遇到的两个小问题

  • 问题一:
- 空指针异常: NullPointerException
- 产生原因: 数组为null, 你还去访问数组中的元素. 
- 解决方案: 给数组赋值. 
  • 问题二:
- 索引越界异常: ArrayIndexOutOfBoundsException
- 产生原因: 你访问了数组中不存在的元素.
- 解决方案: 访问数组中存在的即可.
  • 代码演示
package demo01_array;

/**
 * 演示 数组空指针 和下标越界异常
 */
public class Demo04 {
    public static void main(String[] args) {
        //演示 空指针异常: NullPointerException
        // 定义数组 [0,0,0,0,0]
        int[] arr = new int[5];
        // 把数组置空
        arr = null;
        //访问数组中的元素
        System.out.println(arr[1]);

        // 演示索引越界异常:
        // 产生:ArrayIndexOutOfBoundsException
        System.out.println(arr[6]);
    }
}

5. 遍历数组

  • 步骤
    1. 定义静态数组
    2. for循环遍历数组
    3. 快捷键 itar
  • 代码
package demo01_array;
/*
    案例: 演示如何遍历数组.
    需求:
        1.	定义int类型的数组arr, 存储元素11, 22, 33, 44, 55.
        2.	通过for循环, 遍历数组.
    快捷键:iterator arry  ==> itar
*/
public class Demo05 {
    public static void main(String[] args) {
        //定义静态数组
        int [] arr = {11,22,33,44,55};
        // for 循环遍历数组元素 快捷键 itar
        for (int i = 0; i < arr.length; i++) {
            int i1 = arr[i];
            System.out.println(i1);
        }
    }
}

6.如何获取数组元素的最值

  • 思路
需求:求数组int[] arr = {5, 15, 2000, 10000, 100, 4000};的最大值.
	
	1.定义数组,记录元素
	2.定义一个变量max,记录数组元素的最大值
	3.遍历数组,获取每一个元素
	4.依次比较两个元素(数组的元素和max) 如果当前元素比max大,就将其赋值给max
	5.等待循环结束,max记录的就是最大值
  • 细节
1.把谁作为初始化最大值?
   假设数组的第一个元素为最值.
2.循环开始的时候, 从哪里开始最合适?
   从索引为1的元素开始(第一个值自身和自身不需要比较).
  • 代码
package demo01_array;

/*
    需求:求数组int[] arr = {5, 15, 2000, 10000, 100, 4000};的最大值.
    思路:
        // 1.定义数组,记录元素
        // 2.定义一个变量max,记录数组元素的最大值
        // 3.遍历数组,获取每一个元素
        // 4.依次比较两个元素(数组的元素和max) 如果当前元素比max大,就将其赋值给max
        // 5.等待循环结束,max记录的就是最大值
 */
public class Demo06 {
    public static void main(String[] args) {
        // 定义数组
        int [] arr = {5, 15, 2000, 10000, 100, 4000};
        // 2.定义一个变量max,记录数组元素的最大值
        int max = arr[0];
        // 3.遍历数组,获取每一个元素 快捷键 itar
        for (int i = 0; i < arr.length; i++) {
            int i1 = arr[i];
            //依次比较两个元素(数组的元素和max)
            if (i1 > max ) {
                //如果当前元素比max大,就将其赋值给max
                max = i1;
            }
        }
        // 等待循环结束,max记录的就是最大值
        System.out.println("最大值为: " + max);
    }
}

二、方法

第一步
第二步
下载插件
在这里插入图片描述

1.方法入门基本使用

  • 方法的概念: 把具有独立功能的代码整合到一起,使其成为 具有特殊功能的代码集
  • 方法格式:
// java
	修饰符 返回值的数据类型 方法名(数据类型 参数名1,数据类型 参数名2){
			方法体;
			return 具体的返回值;
	}

// python
def funcName(参数1,参数2):
	方法体
	return 返回值
  • 格式解释:
    1.修饰符:
    	- 目前理解为固定格式 public static
    2.返回值的数据类型
    	- 指的是方法执行完毕后,返回什么类型的结果
    	- 如果明确知道方法没有具体的返回值,则返回值类型必须写成 **void**
    3.方法名
    	- 就是方法的名字 要符合 **小驼峰命名法** 方便调用
    4.参数列表
    	- 简称**形参** 指的是调用方法需要传入什么类型的值。
    5.方法体
    	- 就是前面的逻辑代码 (if for ....) 用来完成某些功能的
    6.return
    	- ' 主要作用是用来结束方法的,捎带着可以返回方法的执行结果。 '
    
  • 注意事项:
    • 方法与方法之间是平级关系,不能嵌套定义。
    • 方法只有被调用才能执行。
  • 定义方法的时候,写的参数列表叫做 形参
    -调用方法需要传入什么类型的值。
  • 调用方法是传入的参数 叫做实参
    • 指的是实际参与运算的数值
  • 方法的功能越单一越好。
    • 单一职责原则
  • 方法的好处:
    • 提高代码的复用性
      -代码
package dome02_method;
/*
    案例: 演示方法入门基本使用
    需求1: 定义方法, 计算两个整数的和.

    java定义方法语言格式:
     修饰符 返回值的数据类型 方法名(数据类型 参数名1, 数据类型 参数名2) {
                     方法体;
                     return 具体的返回值;
     }

    方法的好处: 提高代码的复用性

*/
public class Demo01 {
    // 主函数 程序的入口
    public static void main(String[] args) {
        // 不能在这里定义 不能嵌套定义
        // 调用方法: 1.方法名称()  2.传参  3.接受返回值
        int sum = getSum(1300, 14);
        System.out.println("sum = " + sum);
        System.out.println("----------------[华丽分割线]----------------");

        // 再次调用,代码复用
        int sum1 = getSum(500, 20);
        System.out.println("sum1 = " + sum1);
    }

    /**
     * 定义方法 计算两个整数的和.
     * @param a 计算的第一个整数
     * @param b 计算的第二个整数
     * @return 求和结果
     * 只实现一件事情:单一职责原则
     */
    public static int getSum(int a ,int b){
        int sum = a + b;
        return sum;
    }
}

2. 定义方法实现遍历数组

  • 代码
package dome02_method;
/*
    案例: 定义方法, 遍历数组.
 */
public class Demo02 {
    public static void main(String[] args) {
        // 1.定义静态数组
        //快速抽取方法的快捷键:ctrl + alt + m
        // mac快捷键:option + command + m
        int [] arr = {11,22,33,44,55};
        printArray(arr);
    }

    /**
     * 定义方法,完成数组遍历
     * @param arr 要遍历的数组
     * 如果明确知道方法没有具体的返回值, 则返回值类型必须写成: **void**
     */
    public static void printArray(int[] arr){
        //使用for循环遍历数组 快捷键 itar
        for (int i = 0; i < arr.length; i++) {
            System.out.println("数组元素的下标 " + i);
            System.out.println(arr[i]);
        }
    }
    /*  这是没有返回值的错误写法
    public static int printArray(int[] arr){
        //使用for循环遍历数组 快捷键 itar
        for (int i = 0; i < arr.length; i++) {
            System.out.println("数组元素的下标 " + i);
            System.out.println(arr[i]);
        }
    }*/
}

3.定义方法, 获取数组元素的最大值.

  • 将代码抽取成方法的快捷键:ctrl+ alt + m
  • 代码
package dome02_method;
/*
案例: 定义方法, 获取数组元素的最大值.
*/
public class Demo03 {
    public static void main(String[] args) {
        // 1.定义数组,记录元素值
        int [] arr = {5, 15, 2000, 10000, 100, 4000};

        //调用函数 给形参传入实参arr
        int max = getMax(arr);
        System.out.println("数组最大值 " + max);
    }

    /**
     * 获取数组最大值
     * @param arr   传入的数组
     * @return   数组中的最大值
     */
    public static int getMax(int [] arr){
        // 2.定义变量记录最大值
        // 已经将数组的第一个元素赋值给了max,后面就不需要和自身比较,所以下面的for循环,下标从1开始
        int max = arr[0];

        //循环遍历  直接从1开始即可
        for (int i = 1; i < arr.length; i++) {
            //依次比较两个元素的大小(max比较),如果当前元素比max大,就将该元素赋值给max
            if (arr[i] > max) {
                //如果当前元素比max大,就将该元素赋值给max
                max = arr[i];
            }
        }
        return max;
    }
}

5.方法重载

  • 方法重载的概念:
    -在同一个类中,出现了方法名相同,但是参数列表不同(个数不同 or 对应位置的数据类型不同。) 的两个或者以上的方法时,称为方法重载
    实例:
    	- getSum(int a ,int b)
    	- getSum(int a ,int b ,int c)
    	- getSum(double a ,double b)
    
  • 应用场景
    • 用来解决功能相似或者相同 但是方法名不能从重名的问题。
  • 实例:
    1. 定义方法compare(),用来比较连个整型是否相等。
    2. 要求兼容所有的 整数类型,即(byte, short, int, long)
  • 代码
package dome02_method;
/*
需求:
    1. 定义方法compare(), 用来比较两个整型数据是否相等.
    2. 要求兼容所有的整数类型, 即(byte, short, int, long)

方法重载概念:
    同一个类中, 出现**方法名相同**, **但是参数列表不同**(**个数不同** or **对应的数据类型不同**.)的 两个或者以上的方法时, 称为**方法重载**.

*/

/**
 * 演示方法重载
 */
public class Demo04 {
    public static void main(String[] args) {
        //调用方法
        //比较int类型
        boolean flag1 = compare(10, 20);
        System.out.println(flag1);

        //比较 short类型
        short s1 = 11, s2 = 11;
        boolean flag2 = compare(s1 ,s2);
        System.out.println(flag2);

        //比较byte类型
        byte b1 = 38, b2 = 58;
        boolean flag3 = compare(b1 ,b2);
        System.out.println(flag3);

        //比较long类型
        long l1 = 8765L ,l2 = 543L;
        boolean flag4 = compare(l1 ,l2);
        System.out.println(flag4);
    }
    // 使用方法重载
    // int类型
    public static boolean compare(int a, int b){
        System.out.println("----------------[比较int类型]----------------");
        return a == b;
    }
    // short类型
    public static boolean compare(short a, short b){
        System.out.println("----------------[比较short类型]----------------");
        return a == b;
    }
    // byte类型
    public static boolean compare(byte a ,byte b){
        System.out.println("----------------[比较byte类型]----------------");
        return a == b;
    }
    // long类型
    public static boolean compare(long a ,long b){
        System.out.println("----------------[比较long类型]----------------");
        return a == b;
    }
}

6. java中方法的参数传递问题

  • 需要记忆
'	- 形参如果是基本类型,则形参的改变对实参没有任何影响, 因为传递的是: 数值, 也叫值传递.   		'
'	- 形参如果是引用类型, 则形参的改变对实参有直接影响, 因为传递的是: 地址值, 也叫引用传递.  		'
'	- String虽然是引用类型, 但是它作为形参的时候, 用法和基本类型一致, 传的是数值而不是地址值.  	'
  • 代码 java中的基本数据类型 方法参数传递问题–值传递
package dome02_method;
/*
    案例1: 演示java中的基本数据类型 方法参数传递问题--值传递
 */
public class Demo05 {
    public static void main(String[] args) {
        //基本数据类型 值传递
        int num = 100;
        System.out.println("改变之前: " + num);     //改变之前: 100

        //调用方法 -- 传入基本数据类型
        change(num);
        System.out.println("改变之后: " + num);     //改变之后: 100

    }
    public static void change(int num){
        //传入的参数进行重新赋值
        //新的局部变量 num = 200
         num = 200;
    }
}

  • 代码 java中的参数传递问题 --地址传递
package dome02_method;
/*
    演示java中的参数传递问题 --地址传递
 */
public class Demo06 {
    public static void main(String[] args) {
        // 引用类型作为方法的参数传递
        int[] arr = {11, 22, 33};

        // 调用change方法修改之前获取数组下标为1的元素
        System.out.println("调用change方法之前: " + arr[1]); //调用change方法之前: 22

        //调用change方法,传入引用类型数组
        change(arr);
        // 调用change方法修改之后获取数组下标为1的元素
        System.out.println("调用change方法之前:" + arr[1]); //调用change方法之前:100
    }

    public static void change(int[] arr) {
        // 传入的数组参数重新赋值
        arr[1] = 100;
    }
}

  • 对于值传递 和地址传递的解释
    对于值传递 和地址传递的解释

三、面向对象

1.面向对象入门

  • 面向对象的相关概念
  • 他是一种编程思想,强调的是以对象为基础完成各种操作;吧具有独立功能的代码整合到一起,使其成为具有特殊功能的代码集
  • 思想特点
    • 把复杂的问题简单化
    • 更符合人的思考习惯
    • 把程序员从执行者变成指挥者
  • 总结
    • 万物皆对象
  • 关键字解释
	'类':属性和行为(方法)的集合,是一个抽象的概念。
	'对象':类的具体的实现   例如 设计图纸 ---》 汽车
	'属性': 也叫成员变量 字段 就是事物的外在特征(名词) 对象属性
	'行为':也叫成员方法 就是描述事物能够做什么(动词) 对象方法 
  • 格式
如何定义类:
public class 类名 {
	//属性,名词,全部私有
	
	// 构造方法 空参 全参
	// 类比 python中的 __init__ 魔法方法  初始化
	
	//getXXX()   setXXX()

	//行为方法  动词

}

如何使用类中的成员
	1.创建该类的对象。
		类名 对象名 = new 类名();
		Phone p = new Phone();
	2.通过对象名 的方式调用类中的成员。
		p.call();

2. 面向对象手机类

  • 定义手机类的代码
package demo03_oop;
/*
    需求:定义手机类 Phone
    属性:品牌(brand),价格(price),颜色(color)
    行为:打电话(call),发短信(sendMessage)
 */
/**
 * 自定义手机类,也叫:实体类 POJO类
 */
public class Phone {
    //属性: 品牌(brand)  价格(price)   颜色(color)
    String brand;
    double price;
    String color;

    // 行为 - 成员方法 先不写static

    public void call(String name) {
        System.out.println("给" + name + "打电话");
    }

    public void sendMessage(String name) {
        System.out.println("给" + name + "发短信");
    }
}
  • 创建手机对象代码
package demo03_oop;
/*
    创建Demo1测试类,在main方法中 创建Phone类的对象,并使用其成员变量
 */
public class Deno01 {
    public static void main(String[] args) {
        //创建手机类对象
        Phone p = new Phone();
        // 打印其成员属性和成员方法  注意:成员变量都有默认值
        System.out.println("手机品牌:" + p.brand);  //手机品牌:null
        System.out.println("手机价格:" + p.price);  //手机价格:0.0
        System.out.println("手机颜色:" + p.color);  //手机颜色:null
        System.out.println("----------------[华丽分割线]----------------");

        //给成员属性赋值
        p.brand = "菠萝手机";
        p.price = 998;
        p.color = "绿色";
        //赋值后再次打印手机信息
        System.out.println("手机品牌:" + p.brand);  //手机品牌:菠萝手机
        System.out.println("手机价格:" + p.price);  //手机价格:998.0
        System.out.println("手机颜色:" + p.color);  //手机颜色:绿色
        System.out.println("----------------[华丽分割线]----------------");

        // 调用Phone 类的成员方法
        p.call("郑三炮");  //给郑三炮打电话
        p.sendMessage("王二蛋");   //给王二蛋发短信
    }
}

3.封装

思考: 
	到目前为止,我们虽然已经实现了上述的代码 
	但是我们发现我们目前定义的类,还是有很大的问题,
		因为在外界(测试类中) 可以 直接访问类中的属性 这样做是比较危险的 
		因为用户可能传入一些非法值(举例: p.price = -999.9;)
	针对于这种情况, 我们可以用 封装解决.
  • 封装概述:

    • 封装就是隐藏对象的属性和实现细节,仅对外提供一个公共的访问方式
  • 如何隐藏?

    • 可以通过private 关键字 实现 被它修饰的内容只能在本类中直接访问。
  • 公共访问的方式是什么?

    • 指的是getxxx()setxxx() 方法。
  • 封装的好处是什么?

    • 提高代码的安全性(private保证 ),提高代码的复用性(方法)
  • 封装的弊端是什么? 正对于private

    • 代码的冗余增加了
  • 目前我们在setPrice()方法中是没有做到见名知意的, 只是传入了一个p, 那如何解决这个问题呢?

    • 类似于python的self
    • 通过 this 关键字解决, 它是用来解决局部变量和成员变量重名问题的.
    • this关键字解释: 它表示当前对象的引用, 谁调用, 它就代表谁.
      111
      111
  • 封装:定义手机类代码

package demo03_oop;

/**
 * 自定义手机类私有化类
 */
public class PhonePrivate {
    //品牌
    String brand;

    //价格
    // private 私有变量 外面其他的类无法直接访问
    private double price;

    // 颜色
    String color;

    // 定义公共访问私有属性的方法
    //给price私有属性 设置值 setXXX
    //瑕疵 : 此时的p属性并不能起到 见名知意的效果 修改成price
    /*public void setPrice(double p) {
        //非法值的判断
        if (p > 0) {
            price = p;
        }
    }*/

    public void setPrice(double price) {
        //用局部变量给成员变量赋值
        this.price = price;
    }

    // 读取price私有属性的值  getXxx
    public double getPrice() {
        return price;
    }

    // 行为-成员方法 先不写static
    public void  call(String name){
        System.out.println("给" + name + "打电话");
    }

    public void sendMessage(String name) {
        System.out.println("给" + name + "发短信");
    }
}
  • 封装:创建使用手机对象代码
package demo03_oop;
/*
 创建Demo2测试类,在main方法中 创建PhonePrivate类的对象,并使用其成员变量
*/
public class Demo02 {
    public static void main(String[] args) {
        //创建PhonePrivate对象
        PhonePrivate pp = new PhonePrivate();

        //访问对象属性
        System.out.println("手机品牌:" + pp.brand);

        // 报错:原因price已经私有化了,其他类不能直接访问
        //System.out.println("手机价格:" + pp.price);
        // 使用公共方法访问属性
        System.out.println(pp.getPrice());

        System.out.println("手机颜色:" + pp.color);

        //给属性赋值
        pp.brand = "菠萝手机";
        pp.setPrice(-999.99);
        pp.color = "绿色";

        System.out.println("----------------[华丽分割线]----------------");
        System.out.println("手机品牌:" + pp.brand);
        // 报错:原因price已经私有化了,其他类不能直接访问
        //System.out.println("手机价格:" + pp.price);
        // 使用公共方法访问属性
        System.out.println(pp.getPrice());
        System.out.println("手机颜色:" + pp.color);
    }
}

4. this应用和Java中使用变量的规则

  • 结论(记忆)
  • java中使用变量遵循就近原则,局部有就使用,没有就使用本类的成员变量。
  • 有就使用, 没有就去父类成员位置找,父类没有就直接报错。
  • 代码演示
package demo03_oop;

/**
 * 定义一个学生类
 */
public class Student {
    //成员变量
    int age = 23;

    //成员方法
    public void show(){
        //局部变量
        int age = 20;
        System.out.println(age);
        System.out.println(this.age);
    }
}
  • 代码
package demo03_oop;

/**
 * 创建对象调用方法
 */
public class StudentDemo {
    public static void main(String[] args) {
        Student student = new Student();

        //调用方法
        student.show();
    }
}

5.private和类的构造方法 这是重点

  • 需求:
    • 目前我们发现,如果给一个对象的私有属性赋值,需要调用setxxx() 逐个设置 ,那能不能在创建对象的时候一次性给所有属性赋值呢?
  • 方案:
    • 就是java的构造方法 类似于Python中的魔法方法__init__()初始化方法.
  • 构造方法概念:
    • 主要是用来创建对象的,捎带着可以给对象的属性赋值
  • 格式
//java构造方法格式:
  public 类名(全参) {
    
  }


  public 类名(空参) {
    
  }

// 构造方法的重载

// python构造方法
__init__()

特点:
	1.构造方法名必须和类名完全一致 包括大小写也一致。
	2.构造方法没有返回值,连void都不用写
	3.构造方法中可以有return
	4.构造方法可以重载
	5.如果我们不写构造方法,系统会默认给一个空参构造,如果我们写了 系统就不给了
	6.创建对象的格式可以优化为: 类名 对象名 = new 类名(1, 值2......);
	
  • 定义构造函数学生类代码
    • 构造函数的快捷键 alt +insert
      构造函数第一步
      空参构造完成
  • 全参构造 重复上面的第一步 在第二步的时候 看下图
    在这里插入图片描述
  • windows get&set快捷键:alt +insert
  • windows get&set快捷键 alt + 回车 光标需要放到类上
  • 苹果电脑 get&set快捷键: command + n
    在这里插入图片描述
    在这里插入图片描述
  • 定义构造函数学生类代码
package demo04_private;

public class Student {
    //成员属性全部私有化
    private String name;
    private int age;

    //空参构造
    public Student() {
    }

    //全参构造
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    /*
    python的构造方法
    def __init__(name, age):
        self.name = name
        self.age = age
    */

    // windows get&set快捷键:alt +insert
    // windows get&set快捷键  alt + 回车  光标需要放到类上
    //  苹果电脑 get&set快捷键: command + n
    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 love(){
        System.out.println("我爱她");
    }
}

  • 使用构造函数初始化成员变量
package demo04_private;
/*
    案列:java构造函数测试类
 */
public class Demo01 {
    public static void main(String[] args) {
        // 创建学生对象---使用空参构造函数
        Student stu1 = new Student();
        //给私有属性赋值
        stu1.setName("马佳玉");
        stu1.setAge(23);
        //获取私有属性值
        System.out.println(stu1.getName() + " " + stu1.getAge());
        // 调用成员方法
        stu1.love();
        System.out.println("----------------[华丽分割线]----------------");

        //创建学生对象 ---使用全参构造函数
        Student stu2 = new Student("马佳玉" ,23);
        //给私有属性赋值
        //获取私有属性值
        System.out.println(stu2.getName() + " " + stu2.getAge());

        //调用成员方法
        stu2.love();
    }
}

6. java中的继承

  • 继承概述
    • 实际开发中 我们发现好多类中的部分内容是相似或者相同的,每次写很麻烦,针对于这种情况,我们可以把这些相同(相似)的内容抽取出来到一个类中(父类)。
    • 然后单独的定义到一个类中,然后让那多个类和这个父类产生关系,这个关系叫做继承,在JAVA中,继承用extends关键字表示
  • 格式
'A类继承B类  子承父业'
class A extends B{
	' A类 叫做子类   B类 叫做父类  基类 '

}
  • 好处:

    • 提高代码的复用性
    • 提高代码的可维护性
    • 让类与类之间产生关系,是多态的前提
  • 弊端:

    • 类与类之间的耦合性太强了
    • 开发原则:高聚合 低耦合
  • 父类代码

package demo05_extends;

/**
 * 创建动物基类(父类)
 */
public class Animal {
    //属性 全部私有化
    private String name;
    private int age;

    //空参构造函数
    public Animal() {
    }
    // 全参构造函数
    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }

    //属性 get & set方法
    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 eat(){
        System.out.println("动物会吃");
    }
}

  • 子类代码(Cat)
package demo05_extends;

/**
 * 创建子类 (猫类)   继承动物类  extends Animal
 */
public class Cat extends Animal{

}

  • 使用子类对象
package demo05_extends;

/**
 * 使用子类对象
 */
public class Demo01 {
    public static void main(String[] args) {
        // 创建对象
        Cat cat = new Cat();

        //给属性赋值 并打印
        cat.setName("机器猫");
        cat.setAge(3);
        System.out.println(cat.getName() + "," + cat.getAge());

        //调用对象方法
        cat.eat();
    }
}

7.继承中的成员特点

  • 成员变量
    • 就近原则
  • 构造方法
    • 子空参访问父空参 子全参访问父全参。
  • 成员方法:
    • 就近原则
  • 细节
    1. 子类只能继承父类的非私有成员(构造方法也不能继承)。
    2. 为什么会有方法重写呢?
      • 答: 当子类需要沿袭父类的功能,但是功能主体又有自己额外需求的时候,就可以考虑使用方法重写。
  • 演示成员变量 —就近原则
    成员变量--就近原则
  • 代码演示 super 访问父类 this 访问自己类成员
package demo05_extends;

public class Cat extends Animal{

    // 成员变量
    int num = 20;

    public void show(){
        // 局部变量
        int num = 10;
        System.out.println(num); // 访问:局部变量
        System.out.println(this.num); // 访问:自己类成员变量
        System.out.println(super.num); // 访问:父类的成员变量
    }
}
  • 成员变量就近原则:如果子类全部变量全部注释掉,就近只能访问父类的成员变量
    如果子类全部变量全部注释掉,就近只能访问父类的成员变量
  • 演示构造方法 ---- 子空参访问父空参 子全参访问父全参
    演示构造方法
  • 成员方法就近原则
    成员方法就近原则
  • 代码演示
package demo05_extends;
/*

    成员变量:
        就近原则
    构造方法:
        子空参访问父空参 子全参访问父全参
    成员方法:
        就近原则

    细节:
        1. 子类只能继承父类的非私有成员(构造方法也不能继承)
        2. 为什么会有方法重写?
            当子类需要沿袭父类的功能,但是功能主体 又有自己额外需求的时候,就可以考虑使用方法重写

*/
public class Demo02 {
    public static void main(String[] args) {
        // 成员变量就近原则 没有就往上一级父类中找
        // 创建 Cat类对象
        Cat cat = new Cat();

        //调用show方法
        cat.show();
        System.out.println("----------------[华丽分割线]----------------");

        // 构造方法子空参访问父空参 子全参访问父全参
        Cat cat1 = new Cat();
        System.out.println(cat1.getName() + "," + cat1.getAge());
        System.out.println("----------------[华丽分割线]----------------");

        Cat cat2 = new Cat("橘猫", 3);
        System.out.println(cat2.getName() + "," + cat2.getAge());

        // 成员方法 就近原则
        // 猫吃鱼

        //如果吧Cat类中的eat方法注释掉 调用父类中的eat 会打印 动物会吃
        cat2.eat();
    }
}

  • Animal类
package demo05_extends;

/**
 * 创建动物基类(父类)
 */
public class Animal {
    //属性 全部私有化
    private String name;
    private int age;

    int num = 30;


    public void show(){
        int num = 10;

        System.out.println(num);
        System.out.println(this.num);

    }
    //空参构造函数
    public Animal() {
        System.out.println("Animal空参");
    }
    // 快捷键:alt + 回车  光标定位到类
    // 快捷键:alt + insert
    // 全参构造方法
    public Animal(String name, int age) {
        System.out.println("Animal全参");
        this.name = name;
        this.age = age;
    }
    // ------------[属性的get&set方法]------------
    //属性 get & set方法
    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 eat(){
        System.out.println("动物会吃");
    }
}

  • Cat类
package demo05_extends;

/**
 * 创建子类 (猫类)   继承动物类  extends Animal
 */
public class Cat extends Animal{
    // 子类的成员变量
    int num = 20;

    // Cat全参构造函数
    public Cat(String name, int age) {
        // 子全参  访问==> 父全参
        super(name, age);
    }
    // Cat空参构造函数
    public Cat() {
        // 子全参  访问==> 父全参
        super();
    }

    public void show(){
        // 局部变量
        int num = 10;
        // 1.输出局部变量
        System.out.println(num);
        // 2.子类的成员变量
        System.out.println(this.num);
        // 3.父类的成员变量
        System.out.println(super.num);
    }

    // 成员方法
    public void eat(){
        System.out.println("猫吃鱼");
    }
}

8.继承重写父类方法 @Override 重写父类的方法的关键字

  • 代码
package demo05_extends;
// 手机类  --- 父类
public class Phone {
    //打电话
    public void call(){
        System.out.println("--- 输入手机号码 ---");
        System.out.println("--- 嘟嘟嘟嘟---");
    }
}

========================【子类NewPhone:演示重写父类方法】=====================
package demo05_extends;
/*
    继承父类 并重写父类方法
 */
public class NewPhone extends Phone{
    // @Override 重写父类的方法的关键字

    @Override
    public void call() {
        //调用父类的方法
        super.call();
        System.out.println("手机彩礼:男人就像一朵花,需要人来灌溉他~~~~");
    }
}

-========================【演示重写父类方法】=====================
package demo05_extends;

public class Demo03 {
    public static void main(String[] args) {
        NewPhone newPhone = new NewPhone();

        newPhone.call();
        /*
        * 打印结果:
            --- 输入手机号码 ---
            --- 嘟嘟嘟嘟---
            手机彩礼:男人就像一朵花,需要人来灌溉他~~~~
        * */
    }
}

9.多态

  • polymorphic 英 [,pɒlɪ’mɔːfɪk]
多态概述 :
	多态指的是:同一个事物,在不同的时刻表现出来的不同形态。 
		状态,例如:水(气态 液态 固态)
	
	实例:
		Cat cat = new Cat()//猫类是猫 这个不是多态
		Animal   an = new Cat(); //猫是动物, 这个是多态
		父类引用 =====》  猫的对象

	前提:
		1.必须有继承或者实现关系。
		2.必须父类(父接口)引用指向子类对象。
		3.必须有方法重写,不然多态无意义。
	多态中的成员方法特点(懵):
		成员变量:编译看左,运行看左。
		成员方法:编译看左,运行看右。

	多态的好处:
		父类型可以作为方法的形参类型,这样可以接收其任意的子类对象。
		根据多态的成员方法调用规则“编译看左,运行看右” 传入什么对象,就调用谁的方法。
	
	多态的弊端:
		父类引用不能直接使用子类的特有成员

	如何解决?
		向下转型。
		Animal  an  = new Cat();  向上转型。  double  d  = 10;  隐转
		Cat  cat  = (Cat)an;	  向下转型。  int  a  = (int)d;  强转

  • 代码演示:
========================Animal父类】========================
package demo06_poly;
/*
    Animal 父类
 */
public class Animal {
    // 成员变量
    int age = 30;

    //成员方法
    public void eat(){
        System.out.println("动物会吃~~~");
    }
}

========================Cat子类】========================
package demo06_poly;

/*
    Cat子类
 */
public class Cat extends Animal{
    // 成员变量
    int age = 20;

    //重写父类的eat方法

    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }

    // 成员方法
    public void catchMouse(){
        System.out.println("猫抓老鼠");
    }
}

========================【多态实现】========================
package demo06_poly;
/*
多态概述: 多态指的是 同一个事物 在不同时刻表现出来的不同形态, 状态. 例如: 水(气体, 液体, 固体)
        示例:
						Cat c = new Cat();      //猫类是猫, 这个不是多态.
            Animal       an     = new Cat();  //猫是动物, 这个是多态.
           	父类引用 ==>  猫的对象
        前提:
            1. 必须有继承或者实现关系.
            2. 必须父类(父接口)引用指向子类对象.
            3. 必须有方法重写, 不然多态无意义.
        多态中的成员方法特点(懵):
            成员变量: 编译看左, 运行看左.
            成员方法: 编译看左, 运行看右.
 */
public class Demo01 {
    public static void main(String[] args) {
        //必须父类(父接口)引用指向子类对象
        //多态的体现
        //左             右
        Animal an = new Cat();

        //多态中的成员方法特点(懵):
        //成员变量: 编译看左, 运行看左.
        System.out.println(an.age);  //30

        //成员方法: 编译看左, 运行看右.
        //猫吃鱼
        an.eat();
    }
}

10.多态的好处

  • 父类型 可以作为 方法的形参类型 这样可以接受其任意的子类对象。
    父类型 可以作为 方法的形参类型
  • 根据多态的成员方法调用规则“编译看左,运行看右” 传入什么对象,就调用谁的方法。
  • 代码
========================【父类】========================
package demo06_poly;
/*
    Animal 父类
 */
public class Animal {
    // 成员变量
    int age = 30;

    //成员方法
    public void eat(){
        System.out.println("动物会吃~~~");
    }
}

========================Cat子类】========================
package demo06_poly;

/*
    Cat子类
 */
public class Cat extends Animal{
    // 成员变量
    int age = 20;

    //重写父类的eat方法

    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }

    // 成员方法
    public void catchMouse(){
        System.out.println("猫抓老鼠");
    }
}

========================Dog子类】========================
package demo06_poly;
/*
    Dog类 子类
 */
public class Dog extends Animal{

    //重写父类方法

    @Override
    public void eat() {
        System.out.println("狗吃骨头!!!");
    }
}

========================【多态好处】========================
package demo06_poly;
/*
    定义个printAnimal方法 传入什么对象 调用对应方法
    多态好处:定义方法将形参类型设置成父类类型 接受任何子类对象的传入(多态)
 */
public class Demo02 {
    public static void main(String[] args) {
        //1.创建Cat类对象
        Cat cat = new Cat();
        printAnimal(cat);

        //2.创建Dog类对象
        Dog dog = new Dog();
        printAnimal(dog);
    }
    // 方案1 : 普通写法
    /*
    public static void printAnimal(Cat cat){
        cat.eat();
    }

    public static void printAnimal(Dog dog){
        dog.eat();
    }
    */

    //方案2: 多态的写法
    // 定义方法将形参类型设置成 父类类型 接受任何子类对象的传入 (多态)
    //Animal an = new Cat(); 多态
    //Animal an = new Dog(); 多态
    public static void printAnimal(Animal an){
        an.eat();
    }
}

11.final关键字的用法.

'final关键字的解释'
	关键字 表示最终的意思,可以修饰类 方式 变量。
	修饰类的 不能有子类
	修饰的方法 是最终方法 子类不能重写
	修饰的变量 是一个常量 只能赋值一次
  • 代码
public class Demo01 {
    public static void main(String[] args) {
        final int MAX_VALUE = 30;

        //报错 final修饰的变量 是一个常量 只能赋值一次
        //MAX_VALUE = 100;
        System.out.println(MAX_VALUE);
    }
}
======================[父类]==========================
//报错,final修饰类的  不能有子类
// public final class Fu{

public class Fu {
    //修饰的方法 是最终方法 子类的不能重写。
    //public final void show() {
    public void show() {
        System.out.println("这是绝密文件");
    }
}

=======================[子类]=========================

public class Zi extends Fu{

    //重写父类方法
    @Override
    public void show() {
        System.out.println("随便删除");
    }
}

12.static的用法

 '需要记忆'
 	1.静态可以将 ' 类名. ' 的方式调用。
 	2.静态成员可以被该类所有的对象 '共享' ,这也是决定我们用不用静态的最大原因。
 	3.静态随着类的加载而加载,优先于对象存在。
 	4.静态只能访问静态。
 	5.实际开发中一般 public static final 经常一起用。
  • 代码:
public class Dome02 {
    public static void main(String[] args) {
        // 类名,静态属性
        System.out.println(Student.girl);
        // 报错:name不是静态的  必须 对象名. 的方式调用
        //  System.out.println(Student.name);
        Student stu1 = new Student();
        Student stu2 = new Student();

        // 静态成员可以被该类所有的对象 共享
        System.out.println(stu1.girl);
        System.out.println(stu2.girl);
    }
}

========================【学生类】========================
public class Student {
    String name;
    // 实际开发中一般 public static final 经常一起用
    public static final String girl = "马佳玉";

    //静态方法,只能访问静态成员
    //因为非静态成员只有创建对象才会有,而静态是优先于对象存在的。
    // 即:先进内存的,不能访问后进内存的。
    public static void show(){
        //报错 因为非静态成员只有创建对象才会有,而静态是优先于对象存在的。
        //System.out.println(name);
        System.out.println(girl);
    }
}

13.抽象类

抽象类概念:
	有抽象方法的类一定是抽象类,抽象用 abstract 修饰。
	抽象方法:没有方法体的方法叫抽象方法

特点:
	1. 抽象用 abstract  修饰。
	2. 抽象类不能直接实例化。
	3. 抽象类的子类:
		如果是普通类:必须重写父类中所有的抽象方法。
		如果是抽象类:可以不用重写。

成员特点:
	专业版:变量 常量 构造方法 静态方法 非静态方法,抽象方法
	大白话版:比普通类多一种抽象方法,且还可以不写。
  • 代码
/*
    演示抽象类
 */
public class Demo01 {
    public static void main(String[] args) {
        //抽象类不能直接实例化
        //Animal an = new Animal();  // 报错  动物是动物

        // 抽象类多态
        Animal an = new Cat();
        an.eat();
    }
}

==================【动物抽象类】==================
/**
 * 创建动物类  抽象类
 */
public abstract class Animal {
    // 因为不同的动物吃的内容 不一样 所以该方法不应该有方法体
    // 而是由子类重写
    public abstract void eat();
}

==================【狗抽象类】==================
// Dog 抽象类
public abstract class Dog extends Animal{

    // 如果是抽象类: 可以不用重写父类的抽象方法。  写了不报错
    /*
    @Override
    public void eat() {
        System.out.println("狗吃肉!!!");
    }
    */
}

==================【猫类】==================
public class Cat extends Animal{
    // 如果是普通类: 必须重写父类中所有的抽象方法 否则报错

    @Override
    public void eat() {
        System.out.println("猫吃鱼!!!");
    }
}

14. 接口的基本使用

  • 思考
扩展:假如部分的猫经过训练 学会了飞  请问  飞这个功能应该定义到哪里?
	答案: '  通过: 接口实现    '

记忆:
	抽象类(亲爹):定义整个继承体系的  共性内容  比如:所有的动物都会吃
	接口(干爹):  定义整个继承体系的    扩展内容  比如: 猫会飞
  • 接口概念
接口:
	概念:
		比抽象类更加抽象,里面有且只能有抽象方法和常量
	特点:
		1. 接口用 ' interface ' 修饰。
		2. 类和接口之间是实现关系,用 implements 修饰。
		3. 接口不能实例化。
		4. 接口的子类:
			如果是普通类:必须重写父类中所有的抽象方法
			如果是抽象类:可以不同重写。
  • 代码
/*
    演示接口。
 */
public class Demo01 {
    public static void main(String[] args) {
        //打印常量
        System.out.println(Flying.age);

        //接口不能实例化
        //报错
        // Flying flying = new Flying();

        // 接口多态
        Flying fy = new Cat();
        fy.fly();
    }
}

==================Flying接口实现】==================
// 接口用interface 修饰
public interface Flying {

    // 只能有常量
    public static final int age = 20;

    // 只能有抽象方法
    public abstract void fly();
}

==================【猫类实现Flying接口】==================
public class Cat implements Flying{
    @Override
    public void fly() {
        System.out.println("猫会飞");
    }
}
==================【抽象狗类实现Flying接口】==================
public abstract class Dog implements Flying{
    // 抽象类 不重写父类的抽象方法也不会报错
}

15.类和接口的关系

类和接口的关系:
	类与类:
		继承关系,只能单继承  不能多继承 但是可以多层继承
	类与接口:
		实现关系 可以单实现 也可以多实现 还可以在继承一个类的同时实现多个接口
	接口与接口:
		继承关系 可以单继承 也可以多继承
  • 代码
==================A类】==================
/*
  类与类:继承关系, 只能单继承, 不能多继承, 但是可以多层继承.
 */
public class A{
}
==================B类】==================

/*
  类与类:继承关系, 只能单继承, 不能多继承, 但是可以多层继承.
 */
public class B extends A{

}

==================C类】==================
/*
  类与类:继承关系, 只能单继承, 不能多继承, 但是可以多层继承.
  类与接口:实现关系, 可以单实现, 也可以多实现, 还可以在继承一个类的同时实现多个接口.
 */
public class C extends B implements Inter1, Inter2{
}

==================Inter1接口】==================
/*
类与接口:实现关系, 可以单实现, 也可以多实现, 还可以在继承一个类的同时实现多个接口.
 */
public interface Inter1 {

}

==================Inter2接口】==================
public interface Inter2 {
}


==================Inter3接口】==================
/*
接口与接口:继承关系, 可以单继承, 也可以多继承.
 */
public interface Inter3 extends Inter1, Inter2{
}

16.运动员和教练类案列

案例:运动员和教练
需求:
	1. 已知乒乓运动员(PingPangPlayer)和篮球运动员(BasketballPlayer),乒乓球教练(PingPangCoach)和篮球教练(BasketballCoach)。
	2. 他们都有姓名和年龄,都要吃饭,但是吃的东西不同。
	3. 乒乓球教练叫如何发球 篮球教练叫如何运球和投篮。
	4. 乒乓球运动员学习如何发球,篮球运动员学习如何运球和投篮。
	5. 为了出国交流,跟乒乓球相关的人员都需要学习英语。
	6. 请用所学,模拟该知识。

在这里插入图片描述

  • 代码实现
==================Person类】==================
/**
 * 父类  抽象类 abstract 抽象关键词
 */
public abstract class Person {
    //私有属性 private
    private String name;

    private int age;

    //空参构造
    public Person() {
    }

    //全参构造
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // get & set
    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 abstract void eat();
}

==================Player运动员类】==================
/**
 * 运动员类
 */
public abstract class Player extends Person{
    //子空->父空, 子全 -> 父全
    public Player() {
    }

    public Player(String name, int age) {
        super(name, age);
    }

    // 抽象方法 学习
    public abstract void study();
}

==================Coach类】==================
/**
 *  教练类  抽象类
 */
public abstract class Coach extends Person{
    //子空->父空, 子全 -> 父全
    public Coach() {
    }

    public Coach(String name, int age) {
        super(name, age);
    }

    //抽象方法 教
    public abstract void teach();
}

==================【说英语接口】==================
public interface Speak {

    void speakEnglish();
}

==================【乒乓球运动员类】==================
/**
 * 乒乓球运动员
 */
public class PingPangPlayer extends Player implements Speak{

    public PingPangPlayer() {
    }

    public PingPangPlayer(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat() {
        System.out.println("乒乓球运动员吃烤鸭");
    }

    @Override
    public void study() {
        System.out.println("乒乓球运动员学习如何发球");

    }

    @Override
    public void speakEnglish(){
        System.out.println("乒乓球运动员学习英语");
    }
}

==================【篮球运动员类】==================
/**
 * 篮球运动员
 */
public class BasketballPlayer extends Player{

    public BasketballPlayer() {
    }

    public BasketballPlayer(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat() {
        System.out.println("篮球运动员,吃鸡腿");
    }

    @Override
    public void study() {
        System.out.println("篮球运动员学习如何运球和投篮");
    }
}
==================【乒乓球教练类】==================
public class PingPangCoach extends Coach implements Speak{

    public PingPangCoach() {
    }

    public PingPangCoach(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat() {
        System.out.println("乒乓球吃饺子");
    }

    @Override
    public void teach() {
        System.out.println("乒乓球教练教如何发球");
    }

    @Override
    public void speakEnglish(){
        System.out.println("乒乓球教练学习说英语");
    }
}

==================【篮球教练类】==================
/**
 * 篮球教练
 */
public class BasketballCoach extends Coach{

    public BasketballCoach() {
    }

    public BasketballCoach(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat() {
        System.out.println("篮球教练吃混沌");
    }

    @Override
    public void teach() {
        System.out.println("篮球教练教如何运球和投篮");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值