Java编程必备:IDEA、Eclipse等常用开发工具介绍

一、邂逅 Java

  1. 想使用 Java 进行编程,就必须安装 JDK
  2. JDK:开发环境。(做 Java 代码开发就必须用它。他能将我们写好的 Java 代码进行处理)。
  3. JRE:运行时环境。(写过的 Java 代码想运行起来,就必须有 JRE)。
  4. JVM:Java 虚拟机。(Java 核心。他可以将我们书写后的 Java 代码进行编译,编译成各个操作系统能看到的语言。并执行)。
  5. JDK --> JRE --> JVM
  6. Java 特点:跨平台(操作系统)。

二、Java 中的常用软件

  1. IDEA:功能特别强大,而且插件也很完善。 收费。
  2. Eclipse:曾经非常火,现在也还行。功能相对 IDEA 会差一些。现在依然很多企业再用。 免费
  3. MyEclipse:曾经非常火。现在几乎很少有人使用。 收费。
  4. STS:其实可以理解为就是 Eclipse。只不过他是 Spring 公司出品的。有个别针对 Spring 的支持比较完善。

三、Java 注释

  • 注释是 Java 语言中非常重要的一个环节。
  • 功能:被注释的内容,将不会被代码所执行。起到说明的作用。
arduino 复制代码
// 单行注释   一次注释一行。  ctrl+/
  /*开头 多行注释  结尾*   一次注释多行 
  /** 文本注释  结尾*  一般用于一个例或接口的说明。但是很多公司要求在接口的方法使用文档注释说明该方法的作用。

四、Java 代码书写的规则与规范

  • Java 代码是高级语言、强类型语言。
  • Java 代码严格区分大小写。(规则)。
  • Java 中所使用的符号都必须是英文模式的符号。(规则)。
  • Java 代码需要结束符号。当一段语句结束后必须使用 ; 结尾。(规则)。
  • Java 所有命名不能使用关键字。(规则)。
  • 写代码要有层级关系。一般我们以一队 {} 为层级。所有层级之间使用 table 缩进。 shift + table 可以回缩。

五、Java 中常用术语

  • 包(package):我们可以理解为磁盘中的文件夹。用于区分不同模块的类。
  • 类(Class):写程序就是在写类。我们代码都是写在类中的。他代表一类事物,是一种抽象的。
  • 对象(Object):基于类创建的每一个对象。他是现实生活中存在的一个个个体。(写程序在写类,运行程序在运行对象)。
  • 接口(Interface):比类更抽象。他也是一类事物的同城。与类相似,但不同。(他只定义规范),他不能创建对象。
  • 变量(variable):在内存中开辟一块空间,用来存储我们程序运行时所需要的数据。在运行期间,该值是可能改变的。不到程序运行结束,我们永远不知道该变量最终结果。
  • 常量(了解):定义初期就要赋值。一旦定义该值无法改变。使用 final 修饰。
  • 方法(method):一段通过名字就能执行具体功能的代码。

六、Java 中命名规则与规范

  • 规则及规范:
    • 命名时可以使用英文、数字、$、_。但是不能以数字开头。不允许有特殊符号。不能使用关键字。可以使用但不建议使用中文字符、命名不宜过长。

    • 包命名:所有字母都小写。(一般是公司域名的反写) www.baidu.com com.baidu

    • 类/接口:首字母大写,多个单词组成时每个单词首字母都大写(驼峰写法)。

    • 变量:首字母小写,多个单词组成时每个单词首字母都大写(驼峰写法)。

    • 常量:所有字母大写、多个单词组成使用 _ 分割。

七、Java 中的数据类型。

  • 基本数据类型

    • 四类八种
      • 数值型
        • 整数型

        • byte(几乎不用):字节型, -128~127 256

        • short(几乎不用):短整型, 65536

        • int:整形(默认值) ,用的非常多。 2^64 +-19E

        • long:长整型, int 有可能装不下就用它。会持续增长的也用它。 结尾需要添加一个 l 或 L 191L

        • 浮点型(小数)

        • float:单精度,很少用。 结尾需要添加一个 f 或 F 15.4F

        • double:双精度,默认值。

      • 字符型
        • char:一个字符。可以是一个中文、一个英文、一个数字。 必须使用一对单引号包裹。 '中'、'a'。
      • 布尔类型
        • boolean: true false
  • 引用数据类型

    • 无数种,除了基本数据类型都是引用数据类型
      • 我们只要自己创建了一个类,就等于声明了一种数据类型。
      • JDK 中为我们提供了一些常用的引用数据类型。
        • String:字符串 --> 一串字符。用的最多最多最多的。 必须 "" 一对双引号包裹。 "你好中国"。在字符串内的数据都是原样输出。

        • Date:日期类。

        • Class:类

        • Object:对象

        • Array:数组

        • List/Set/Map:集合

        • Calendar:日历类。(日期的运算)。

        • BigDecimal:精确型小数。一般用于 Money。

        • 八大基本数据类型对应的包装类

        • byte --> Byte

        • short --> Short

        • int --> Integer

        • long --> Long

        • float --> Float

        • double --> Double

        • char --> Character

        • boolean --> Boolean

    • 行业内,又自成一种规范(这种规范并不是 Java 官方认可的)。简单类型
      • 他并不是官方推出的。是业内人士(广大程序员们),默认自主承认的一种数据类型。他会把我们 基本数据类型 + 常用引用数据类型放到一起的称呼。 8 大把基本数据类型 + 包装类 + String + BigDecimal 等等...

八、Java 中的数据类型转换(了解)

  • 基本数据类型转换

    • 在 Java 中 boolean 类型不参与任何转换。
    • 隐士转换(自动转换)(常用)
      • 小转大
        • byte、short、char 三种不能相互转换。

        • byte、short、char --> int --> long --> float --> double

    • 显示转换(强制转换)(慎用)
      • 大转小
        • 需要强制使用 () 转换 例如 byte b = (byte)32Z

        • 一定要慎用,因为可能会丢失精度。

  • 引用数据类型转换(常用)

    • 只要能包含的情况下。我们可以使用 () 为前缀。使用具体数据类型进行转换 (String)"abc"。

九、Java 中的变量。

  • 在内存中开辟一块空间,用来存储我们程序运行时所需要的数据。在运行期间,该值是可能改变的。不到程序运行结束,我们永远不知道该变量最终结果。

  • 变量如何使用

    • 变量的声明

数据类型 引用名;

int i;

    • 变量的初始化

引用名 = 值;

i = 10;

    • 建议写法 声明 + 初始化

数据类型 引用名 = 值;

int i = 10;

    • 在同一块作用域内,变量的名字是禁止重复的(花括号)。
    • Java 基础中。若程序想运行就必须有一个主方法。主方法就是程序运行的入口。 简写 main psvm

public static void main(String[] args){ // 这里面就是需要执行的代码。 }

    • 输出语句,简写 sout

System.out.println(「需要输出的语句」);

    • Demo

package day01; /** * 数据类型及变量 * public class _01_Variable { // 主方法,程序的入口。 public static void main(String[] args) { // 使用变量定义一些数据类型 byte b = 10; short s = 20; int i = 30; long l = 40L; float f = 12.3F; double d = 20.2; char C = 『a』; boolean bl = true; String str = 「今天真开心,终于可以写代码了」; // System.out.println(需要输出的语句); 简写 sout System.out.println(「变量 b」 + b); System.out.println(str); final int USER_ID = 123; } }

十、Java 中的常量(了解)

  • 声明后不能直接使用,若想使用必须初始化。(创建后必须赋值)
  • 修饰符 final
  • 例如 final int USER_ID = 22;

十一、运算符

  1. 赋值运算符
  • = 赋值, Java 是从右向左赋值。需要注意数据类型。
  1. 算数运算符
        • / ++ -- %
    • 号:
    • 在正常数学运算时,做加法运算。

    • 存在字符串时,做连接符号。

    • / Java 中除法不存在小数。0 不能做除数。

    • ++ 自增 1

    • -- 自减 1

    • 自增自减:++在前 先加后用。 ++在后先用后加。

    • % 取余。 取除法的余数。

  1. 条件运算符
  • 条件运算符得到的结果一定是一个 boolean 值。也就意味着结果只有真和假

  • String 类型比较使用 equals() 方法.

  • = < <= == !=

  1. 逻辑运算符
  • 作用:就是用来链接条件运算符的。

  • 很多时候我们一个条件不够用的时候。需要多个条件。那么就需要使用逻辑运算符来链接多个比较运算符。

  • &&:逻辑与,并且的意识。多个条件都为真,结果才是真。

  • ||:逻辑或,或者的意识。多个条件中任意一个为真,结果才是真。

  • !:取反,真亦假,假亦真。

  • 作业:自行了解 短路机制。

  1. DEMO
ini 复制代码
package day01;
   
   /**
    * 运算符
    * /
   public class _02_Operator {
       public static void main(String[] args) {
           // +
           System.out.println(1 + 2);  // 正常数学运算
           System.out.println(「嘿嘿」 + 「1」 + 「2」);  // 看到双引号就是字符串。做连接符
           // 除法没有小数,且没有四舍五入。
           System.out.println(5/2);
           // System.out.println(1/0);
           System.out.println(「----------- 自增自减 --------------」);
           int i = 3;
           System.out.println(i++);
           System.out.println(i);
           System.out.println(「---------  取余  -----------」);
           System.out.println(5%2);
   
           System.out.println(「-------- 条件运算符 --------」);
           System.out.println(5 > 3);  // true
           System.out.println(3 != 4); // true
           System.out.println(「---------- String 字符串比较 ------------」);
           String str1 = 「zhangsan」;
           String str2 = 「lisi」;
           System.out.println(str1.equals(str2));      // false
           System.out.println(「abc」.equals(「abc」));    // true
           System.out.println(「---------- 逻辑运算符 ---------」);
           int a = 18;
           System.out.println(a > 10 && a <= 18);  //true
           System.out.println(a > 15 || a < 17);   // true
       }
   }

十二、分支语句

  • 分支语句会影响程序的走向。正常程序是从上至下依次执行。
  1. 判断
  • if 如果...

if(条件表达式){ // 若条件表达式的值为 true,则执行该语句块内的代码。 } // if 内的语句是由可能执行到,也可能执行不到。 package day01; /** * if 判断 * / public class _03_if { public static void main(String[] args) { // 设置一个 age 年龄。若 age >= 18 则可以包宿。 int age = 19; if(age >= 18){ System.out.println(「wa o ~ 终于可以包宿了~」); } System.out.println(「.... 后续代码执行」); } }

  • if...else 如果... 否则...
csharp 复制代码
if(条件表达式){
         // 若条件表达式的值为 true,则执行该语句块内的代码。
     } else {
         // 若不满足条件则执行该语句块内的代码。
     }
     // if..else 无论如何, if || else 一定会执行到里面某一个语句块。
     
     package day01;
     
     /**
      * if...else 判断
      */
     public class _04_if_else {
         public static void main(String[] args) {
             // 设置一个 age 年龄。若 age >= 18 则可以包宿。
             int age = 17;
     
             if(age >= 18){
                 System.out.println(「wa o ~ 终于可以包宿了~」);
             } else {
                 System.out.println(「小屁孩,回家睡觉吧~」);
             }
     
             System.out.println(「.... 后续代码执行」);
         }
     }
  • if...else if..else 如果... 否则 如果... 否则...

    • 若满足某一个条件后,当前判断立即结束。后续代码继续执行。
scss 复制代码
if(条件表达式){
         // 若条件表达式的值为 true,则执行该语句块内的代码。
     } else if(条件表达式) {
         // 若条件表达式的值为 true,则执行该语句块内的代码。
     } else if(条件表达式) {
         // 若条件表达式的值为 true,则执行该语句块内的代码。
     }
     ...
     else {
        // 若都不满足条件则执行该语句块内的代码。     
     }
     
     package day01;
     
     /**
      * if...else if 判断
      */
     public class _05_if_else_if {
         public static void main(String[] args) {
     
             double money = 500;
             // 请女朋友吃饭。
             if(money >= 1000){
                 System.out.println(「走,吃海鲜去」);
             } else if(money >= 600){
                 System.out.println(「走,吃西餐吧」);
             } else if(money >= 400){
                 System.out.println(「走,吃火锅吧」);
             } else if(money >= 200){
                 System.out.println(「吃,吃烤肉吧」);
             } else {
                 System.out.println(「回家吃面条吧!!」);
             }
         }
     }
  1. 循环
  • for:已知次数的循环

for(循环变量初始值;循环条件;步进语句){ 循环体;(循环需要执行的代码) } package day01; /** * for 循环 */ public class _06_for { public static void main(String[] args) { // 循环变量初始值:一个初始变量,我们需要开始的起始数字。 // 循环条件:条件表达式。当条件表达式的结果为 true 则执行循环体。false 则停止循环。 // 步进语句:控制循环变量初始值的增减,目的是停止循环。 // 计算从 1 ~ 100 的和; int sum = 0; // 累加结果 for(int i = 1;i <= 100;i++){ sum = sum + i; } System.out.println(sum); } }

    • while:未知次数的循环

while(循环条件){ 循环体; } package day01; /** * while 循环 */ public class _07_while { public static void main(String[] args) { // 计算从 1 ~ 100 的和; int sum = 0; // 累加结果 int i = 1; while(true){ if(i > 100){ break; // 停止循环 } sum = sum + i; i++; } System.out.println(sum); } }

    • do..while:无论是否成功都先执行一次

do{ // 循环体 }while(循环条件); package day01; /** * do...while 循环 */ public class _08_do_while { public static void main(String[] args) { // 计算从 1 ~ 100 的和; int sum = 0; // 累加结果 int i = 1; do{ sum += i; i++; }while(i <= 100); System.out.println(sum); } }

十三、Java 中的数组

  • 定义:数组就是相同数据类型 的集合。在内存中开辟一块连续的内存空间 用来存储我们所需要的数据。数组的长度一经定义无法改变

  • 特点:

    • 存储相同数据类型

    • 数组是有序的。(存储数据的顺序)。

    • 长度无法改变。

  • 语法规则:

ini 复制代码
// 数组的定义
  // 数据类型[] 引用名;
  // 后续再初始化
  
  // 数据类型[] 引用名 = new 数据类型[3];
  // 数据类型[] 引用名 = new 数据类型[] {值 1,值 2,值 3,值 4}
  // 我们都使用简易方式创建书写
  // 数据类型[] 引用名 = {值 1,值 2,...}
  • 对数组的顺序表示我们称之为索引(下标)。索引是从 0 开始的。
csharp 复制代码
package day01;
  
  /**
   * 数组
   */
  public class _09_Array {
      public static void main(String[] args) {
          // int[] arr1 = new int[3];    // 3 长度的数组
          // int[] arr2 = new int[]{1,2,3,4};
  
          // 数组声明并初始化
          int[] arr = {1,2,6,3,2};
          // 数组是有序的。对顺序的表示我们称之为 索引(下标)。索引从 0 开始
          System.out.println(「arr 数组中第二个元素为:」 + arr[1]);
  
  
          // 若想一次性将数组中的所有元素都取出。
          // 数组的最大索引等于 数组的长度 - 1。
          // 数组中存在一个属性。 .length  他就是数组的长度
          System.out.println(「该数组长度为:」 + arr.length);
  
          System.out.println(「=====================」);
          // 数组的遍历
          // i 就是我们所谓的「索引」。
          for(int i = 0;i < arr.length;i++){
              System.out.println(arr[i]);
          }
          System.out.println(「♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥」);
          // 对于数组 还有后面学习的集合。我们有一种增强 for 循环的方式遍历
          // for(数据类型 引用名 : 数组名){
          //     通过引用名获取到每一个元素
          // }
          for(int temp : arr){
              System.out.println(temp);
          }
      }
  }

十四、Java 中的方法(重点)。

  • 定义:其实他就是一段有名字的代码。该段代码可以完成指定的功能。

  • 为什么要用方法?

    • 代码的复用:我们可以将一段完整的功能封装为一个方法。多处使用到该功能时直接调用该方法即可。

    • 易于维护:我们针对于某一种功能封装后,多处都可以使用。当我们将方法内的内容改变后。多处代码也随之更改。这样就可以实现一处修改。多处实现。

    • 单一原则:一个方法只完成一件事情。

  • 方法的组成

    • 方法的首部声明

    • 方法体

  • 语法

scss 复制代码
// 带有 [] 包裹的,是可选择性写或不写的。
  [权限修饰符] [修饰符] 返回值类型 方法名([形参 1,形参 2,...])	// 方法的首部生命
  {
      // 方法体
      // 需要执行的功能
      [return xxx;]
  }
  • 权限修饰符:public 公共的,当前项目中谁都可以访问 。在什么位置能够访问到我们的当前的方法。

  • 修饰符:

    • static:静态的。可以通过类名.方法名的方式调用。若是本类方法。则可以直接在静态方法中直接调用,不需要类名。

    • abstract:抽象的。(接口部分讲解)

    • final:最终的。(了解。继承部分说一下)

  • 返回值类型:我们执行方法后,需要该方法为我们返回什么类型的数据。若需要则需要定义返回值类型。若不需要返回任何数据也必须使用 void 占位。

  • 方法名:该方法的引用名,我们可以通过该引用名找到该方法。

  • 形参列表:当我们调用方法时,是否需要传递某些数据。

    • 形参列表本质上可以理解为是我们方法中一些变量。只不过这个变量只做了声明。未初始化。(只创建了,没赋值)。当该方法的调用者调用时,将具体的值传入。

    • 方法的形参可以是 Java 中的任意类型。可以是 0 ~ 任意个。但是不建议过多。一般很少有超过 5 个的。

  • 方法体:该方法具体需要实现的功能。

  • return 语句:

    • 有返回值类型时:必须使用 return 语句。我们需要在 return 语句后返回一个数据,该数据的数据类型必须与返回值类型相容。(一般我们的返回值的数据类型都会与方法的返回值类型一致)。

    • 若没有返回值类型时:可以有也可以没有。若写 return 则不能返回任何数据。 return 只代表方法的结束。

    • return 是方法的最后一条可执行语句。

  • 方法需要定义在类中。与主方法平齐。方法不能嵌套。

csharp 复制代码
package day01;
  
  public class _10_method {
      // 主方法
      public static void main(String[] args) {
  
      }
  
      // 无参数无返回值的方法
      public static void show(){
          System.out.println(「我是无参数我返回值的方法」);
      }
  
      // 有参数无返回值的方法
      public static void addTwo(int a,int b){
          System.out.println(「两数之和为:」 + (a + b));
      }
  
      // 无参数有返回值的方法
      public static String showTwo(){
          return 「爱你」;
      }
  
      // 有参数有返回值的方法
      public static int sub(int a,int b){
          return a - b;
      }
  
      // 没有返回值的 return 语句
      public static void add(int a,int b){
          if(a > b){
              System.out.println(「哈哈」);
              return;
          }
          System.out.println(「a < b 我输出了」);
      }
  }
  • 方法的调用。

    • 我们暂时先都说静态方法。

    • 若是本类中。静态方法可以直接调用静态方法。不需要类名。

    • 其他类中若调用静态方法。(前提是访问权限修饰符能够访问到)。需要类名.方法名() 方式调用。

  • 方法的重载

    • 在同一个类中,方法名相同,参数列表不同(长度,类型,不同类型的顺序不同)

package day01; /** * 方法的重载 */ public class _11_Overload { public void add(int a,String b){ }; public void add(String a,int b){ } }

  • 方法不能主动执行。它必须被调用才能执行。

十五、Java 面向对象思想(重点)。

  • 现实生活中存在的一类事物。存在着某些共性(共性抽取)。泛指一类事物。他是抽象的,是现实生活中不存在的。

  • 类是对象的模板。

    • 静态属性:属性。

    • 动态行为:方法。

    • 写程序在写类。运行程序运行的是对象。
  1. 对象
  • 对于一类事物中的具体存在的个体。我们称之为对象。他是显示生活中真实存在的个体。

  • 对象是类的实例。

  • 每个对象都应该存在类的属性及方法。但是每个对象都有自己的属性值。

  • 创建对象就需要构造方法。

  1. 构造方法
  • 构造方法也是方法,只不过它是一种特殊的方法。
  • 要求方法名与类名相同,没有返回值,也不需要 void 占位。构造方法可以被重载。
  • 构造方法的作用:
  1. 创建对象(最大的作用)。

  2. 还可以在创建对象时为其赋值。

    • 使用构造方法创建对象需要使用 new 关键字。
    • 只要我们写了一个类,就存在构造方法。若我们没有明确的写出构造方法。那么系统会送我们一个无参数无方法体的空构造方法。若我们明确的写出了其他形式(带参数)的构造方法。那么系统将不再赠送。
    • 无参及有参构造方法的书写

package day02._01_obj; public class Student { public String name; public Integer age; // 我们没有明确写出构造方法,系统会送我们一个无参数五方法体的构造方法。若写了则不送了,需要则自己写。 // 一般我们只要写了有参构造方法,都会手动添加一个无参数构造方法。(后期框架会调用) public Student() { } // 若我们自己书写了携带参数的构造方法,那么系统将不再赠送。 public Student(String name,Integer age){ // Java 中存在就近原则。谁离着进, name 就指向谁。 // 若方法中的形参名与类中的属性名一致,我们可以使用 this 关键字。 // this 指向本类。 this.name = name; this.age = age; } public void eat(){ System.out.println(「中午订一份得了」); } @Override public String toString() { return 「Student{」 + 「name=『」 + name + 』\『』 + 「, age=」 + age + 『}』; } }

    • 创建对象

package day02._01_obj; public class ObjTest { public static void main(String[] args) { // 创建对象 Student stu = new Student(); // Student: 数据类型 // stu:引用名 // new: 内存分配符。(只要看到 new,就是在内存中开辟空间) // Student():构造方法,创建对象。 // 调用成员属性及方法(非 static 修饰的)。我们使用 对象名.属性/方法 名调用。 stu.name = 「张三」; stu.age = 35; stu.eat(); System.out.println(stu); Student stu2 = new Student(「李四」,12); System.out.println(stu2); } }

  1. 封装
  • 将内部细节隐藏起来。对外只暴露统一的接口。
  • 好处:安全、便捷、高效、解耦。
  • 访问权限修饰符:

| 四种访问权限修饰符 | 不同包下的不同类 | 相同包下的不同类 | 本类 | | --------------------------------------- | -------------------------------------------------- | ---------------------------------- | ---------------------------------- | | public 公共的 | √ | √ | √ | | protected 受保护的(了解) 父子类相互使用 | X(继承下可以使用) | √ | √ | | 默认的(什么都不写) | X | √ | √ | | private 私有的 | X | X | √ |

    • 我们最常用的 (public private)

    • private 的权限最小,最适合做封装。也是我们用的最多的用于封装的。但是不代表只有 private 能做封装。其他任何访问权限修饰符都可以做封装。只不过 private 用的最多。

    • 我们利用封装思想。可以完成标准 JavaBean。 (将来这种 JavaBean 他可以用于接受 Web 用户传递的请求时候携带的参数。也可以与数据库做数据交互使用)。

    • 标准 JavaBean

      • 所有属性私有化。

      • 为每一个属性都提供一对共用 Getter/Setter 方法。

      • 提供有参无参构造方法(可选)。

      • 若需要展示当前对象数据(调试)。提供 toString 方法。

package day02._02_createObj; /** * 封装 * 封装标准 JavaBean */ public class Student { // 所有属性私有化 private Long id; private String name; private Integer age; public Student() { } public Student(Long id, String name, Integer age) { this.id = id; this.name = name; this.age = age; } // Set 方法可以对非法数据进行验证。 public void setName(String name){ if(name.equals(「二狗」)){ this.name = 「帅哥」; return; } this.name = name; } public String getName(){ return this.name; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return 「Student{」 + 「id=」 + id + 「, name=『」 + name + 』\『』 + 「, age=」 + age + 『}』; } }

    • 测试类

package day02._02_createObj; public class StudentTest { public static void main(String[] args) { Student stu = new Student(); // 设置属性值 stu.setName(「二狗」); // 获取属性值 System.out.println(stu.getName()); } }

  1. 继承
  • 继承在 Java 是广泛存在的,所以在 Java 中我们将继承关系又称之为 "泛化关系"。是类就存在继承关系。若一个类没有明确写出继承关系。那么这些类都继承所有类的父类 Object 类。

    • 父类(被继承类)、基类

    • 子类(继承类)、派生类

    • 继承的关键字 extends
    • 继承不要乱继承。继承必须存在关系才可以继承 is - a。是一种关系。
    • 继承的作用:子类可以继承父类中所有非私有(private)修饰的属性和方法。
    • 我们在使用时,一般会将父类中定义基础的属性及方法。子类继承后就可以拥有父类中定义的基础属性和方法。同时可以扩展自己的属性及方法。所以子类就是对父类的扩展。简化代码。
    • Java 中是单继承。一个子类只能存在一个直接父类。一个父类可以存在若干个子类。
    • Java 中是可以存在继承链的,但不宜过多。
    • 继承中,若存在同名属性,则就近原则(本类,子类中的属性值)。
    • 方法的重写:发生在继承/实现时候。子类重写了父类的方法。方法名相同,参数列表和返回值类型都相同。
    • 我们可以使用 @Override 注解来测试该方法是否为重写方法。若该注解报错则说明不是重写方法。一般重写的方法我们都会在该方法上面贴上 @Override 来标识。
    • 父类 Animal

package day02._03_extends; /** * 动物类 * 父类 */ public class Animal { public String name = 「小猪」; public Integer age; public void eat(){ System.out.println(「动物吃饭」); } }

    • 子类 Dog

package day02._03_extends; /** * 子类 * 继承 Animal 动物类 */ public class Dog extends Animal{ public String name = 「gogo」; @Override public void eat() { System.out.println(「小狗吃骨头」); } }

    • 子类 Cat

package day02._03_extends; /** * 子类 * 继承 Animal 动物类 */ public class Cat extends Animal{ @Override public void eat() { System.out.println(「小猫吃鱼」); } }

    • 子类 Tiger

package day02._03_extends; /** * 子类 老虎 * 继承 Animal */ public class Tiger extends Animal{ @Override public void eat(){ System.out.println(「小老虎吃肉肉」); } }

    • 测试类

package day02._03_extends; public class ExtendsTest { public static void main(String[] args) { Dog dog = new Dog(); dog.age = 2; System.out.println(dog); System.out.println(「===============」); dog.eat(); Cat cat = new Cat(); cat.age = 2; System.out.println(cat); System.out.println(「===============」); cat.eat(); System.out.println(「♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥」); // 饲养员给动物喂食 Person person = new Person(); Cat C = new Cat(); Dog d = new Dog(); Tiger t = new Tiger(); person.feed(t); } }

  1. 多态
  • 类多种形态的表现

  • 实现多态的条件

    • 继承(实现)。

    • 方法的重写。

    • (类 --> 对象 --> 方法)动态绑定。

    • 向上转型(李氏代换)。 --> 自动转换
    • 父类的引用 --> 指向子类的对象。
    • Demo
    • 父类 Animal

package day02._04_polymorphism; /** * 动物类 * 父类 */ public class Animal { public String name = 「小猪」; public Integer age; public void eat(){ System.out.println(「动物吃饭」); } }

    • 饲养员类

package day02._04_polymorphism; /** * 饲养员类 * * 饲养员要给小动物喂食 */ public class Person { // Animal an = new Tiger(); public void feed(Animal an){ an.eat(); } }

    • 测试类

package day02._04_polymorphism; public class ExtendsTest { public static void main(String[] args) { // 饲养员给动物喂食 Person person = new Person(); // 创建父类类型 Animal // Animal an = new Animal(); // 执行结果为 动物吃饭 // 父类的引用 --> 指向子类的对象。 Animal d = new Dog(); Animal C = new Cat(); Animal t = new Tiger(); person.feed(t); } }

    • 父类的引用指向子类的对象。这种方式创建出来的对象是谁?

      • 既不属于父类,也不属于子类。

      • 该对象 - 编译期(代码未运行时): 用的属性及方法看 = 左边。 - 运行期(代码跑起来后): 用的属性及方法看 = 右边。

    • 若想使用子类特有的属性及方法 必须向下转型
    • 向下转型必须是向上转型得到的对象才可以
    • 不要随意使用。小心类型异常。

package day02._04_polymorphism; public class ExtendsTest { public static void main(String[] args) { // 饲养员给动物喂食 Person person = new Person(); //Cat C = new Cat(); //Dog d = new Dog(); //Tiger t = new Tiger(); // 创建父类类型 Animal // Animal an = new Animal(); // 执行结果为 动物吃饭 // 父类的引用 --> 指向子类的对象。 Animal d = new Dog(); Animal C = new Cat(); Animal t = new Tiger(); person.feed(t); // 向上转型得到的对象 System.out.println(d.name); // 父类=小猪 子类=gogo 结果为小猪 父类属性值 d.eat(); // 父类=动物吃饭 子类=吃骨头 结果为 小狗吃骨头 // 若想使用子类特有的属性及方法 必须向下转型 // 向下转型必须是向上转型得到的对象才可以 Dog dog = (Dog) d; System.out.println(dog.color); dog.run(); } }

十六、接口(重点)

  • 接口也代表了一类事物。

  • 接口他是抽象的,他比类更抽象。他更多的是提供了一组规范。提供模板。

  • 接口关键字 Interface。接口不提供实现。他不能创建对象。

    • JDK8 之前:
      • 接口中只能存在静态常量。默默人修饰符 public static final。

      • 接口中 方法都是抽象方法。由 abstract 修饰。抽象方法只有方法的首部声明,没有方法体。默认修饰符 public abstract 。他是提出一组规范让他去使用。

    • JDK8 之后:
      • 出现了静态方法、默认方法。 JDK9 之后出现了私有方法。(存在方法体的)。
  • 接口不是类,不能创建对象。所以他的一切方法都需要交给别人去处理。(实现类)。

  • 接口就是用来定义规范的。定义规范后由类去实现接口。并实现接口中所有抽象方法。这些实现接口功能的类我们称之为实现类。

  • 类去实现接口的关键字 Implements。

    • 提供规范。

    • 解决 Java 单继承问题。

  • 一个类只能继承一个直接父类。但是可以实现若干个接口。

  • 很多时候,我们都是用 接口 --> 实现类方式书写代码。这样代码的可扩展性更高。

  • 接口 A DEMO

csharp 复制代码
package day02._05_Interface;
  
  public interface A {
  
      void eat();
  }
  • 接口 B DEMO
csharp 复制代码
package day02._05_Interface;
  
  public interface B {
  
      void run();
  
      void show();
  }
  • 实现类 DEMO
less 复制代码
package day02._05_Interface;
  
  /**
   * 接口实现类
   * 一个类可以继承一个直接父类,同时实现多个接口。使用 , 分割。
   */
  public class InterfaceImpl extends Animal implements A,B{
  
      @Override
      public void eat() {
          System.out.println(「他要吃 XXX」);
      }
  
      @Override
      public void run() {
          
      }
  
      @Override
      public void show() {
  
      }
  }
  • 测试类
java 复制代码
package day02._05_Interface;
  
  public class InterfaceTest {
  
      public static void main(String[] args) {
          // 创建 A 接口对象
          // 接口 实现类的方式创建
          A a = new InterfaceImpl();
  
          B b = new InterfaceImpl();
  
          a.eat();
  
          b.run();
  
          b.show();
      }
  }

十七、异常处理

  • 当我们书写代码。运行程序时都可能出现各种各样的问题。此时就与异常处理相关。

  • 程序出现异常有两种情况

    • Error:错误,灾难性的、致命的。一般无法通过小的改动而去拯救。 相当于得了绝症。

    • Exception:异常,一般是书写代码错误或逻辑错误导致的。通常通过一些小的代码改动就能解决。 相当于得了个小感冒。

  • 异常分类

    • 编译期异常:编译期就是代码未运行期间的错误。
      • 要么就是我们自己代码敲错了。

      • 系统级的。这种一般我们简单处理即可。

    • 运行期异常:
      • 代码跑起来之后才会出现的异常。这种普遍就是程序员们逻辑出现问题。需要修改代码。(我们一般都处理这个运行时异常。) RuntimeException
  • 我们一般都是针对运行期异常进行处理

  • 异常处理有三种方式

    • try/catch/finally:我们自己捕获到异常并处理异常

      • try:语句块中是可能出现异常的代码。

      • catch:若出现了异常,那我们如何处理该异常。

      • finally:无论该代码是否出现异常都会执行。(一般用于关闭资源)

package day02._06_exception; /** * 捕获异常 * try catch finally */ public class Try_Catch { public static void main(String[] args) { // 在 try 中捕获可能出现的异常 // 在 catch 中处理出现的异常。 try{ System.out.println(1/0); System.out.println(「若代码没出现异常执行该代码...」); } catch (RuntimeException e){ // 需要捕获的异常类型。 e.printStackTrace(); // 在控制台中显示异常。 // 若出现了该类型的异常则执行该语句块 System.out.println(「出现了异常,我们去处理该异常」); } finally { // 无论是否产生异常,都执行该语句块 System.out.println(「关闭资源」); } } }

    • throws:抛出异常类型。

      • 在方法上面声明。抛出的是异常类型。

      • 所谓的抛出异常,其实就是自己不处理该异常。向上抛出。谁调用我谁就来处理该异常。若谁都不处理这个异常。那么最终交给 Java 虚拟机来处理。 Java 虚拟机会直接采取中断处理(直接停止我们程序执行)。

      • 一般一些编译期异常用的较多。例如文件是否能够找到。磁盘是否存在这些。

package day02._06_exception; import Java.io.FileNotFoundException; /** * 异常抛出 */ public class ThrowsTest { public static void main(String[] args) { ThrowsTest t = new ThrowsTest(); try { t.showTwo(); } catch (FileNotFoundException e) { throw new RuntimeException(e); } } public void showTwo() throws FileNotFoundException{ System.out.println(「被调用了」); show(); } public void show() throws FileNotFoundException { System.out.println(「产生异常的代码.」); System.out.println(1/0); System.out.println(「异常抛出」); } }

    • throw:在代码中抛出指定异常。

      • 一般我们可以自定义异常抛出的信息。很多时候我们在 WEB 程序中,作为自定义指定内容输出。

package day02._06_exception; public class LoginTest { public static void main(String[] args) { LoginTest login = new LoginTest(); // 该方法是抛出了异常的 try { login.login(); System.out.println(「登录成功」); } catch (RuntimeException e) { System.out.println(「给用户展示错误消息:」 + e.getMessage()); } } public void login() throws RuntimeException{ // 假设用户传递了用户名 zs 密码 123 String username = 「zs1」; String password = 「123」; // 调用方法去处理登录请求 checkUserNameAndPassword(username,password); } public void checkUserNameAndPassword(String username,String password){ // 对比用户名是否正确 if(!(username.equals(「zs」) && password.equals(「123」))){ throw new RuntimeException(「账号密码有误」); } } }

十八、集合(数据结构)

  • 集合概述:可以存储多个数据。集合中也可以存储多种数据类型(但是实际开发中不建议这么做)。集合中只能存储引用数据类型。

  • 集合的分类:

    • 单列集合:Collection 父接口 --> (List 接口,Set 接口)

    • 双列集合:Map 父接口

    • List:(列表)

      • List 集合中有多个实现类。

      • 我们最常用的 ArrayList。他的底层数据结构为 动态数组。本质上就是数组。只不过可以自动扩容。初始值为 10.扩容机制为 1.5 倍。

      • 特点:

        • 可以存储多种数据类型(实际开发中不建议这么做)。

        • 有序的。(索引)。

        • 可以存储重复数据。

        • 存在扩容机制。

      • 案例:

package day02._07_gather; import Java.util.ArrayList; import Java.util.List; /** * List 接口 * 实现类 ArrayList */ public class _01_ArrayList { public static void main(String[] args) { List list = new ArrayList(); // 添加数据 add() 方法。 list.add(「abc」); list.add(1); list.add(true); // 获取数据 System.out.println(list.get(0)); System.out.println(list.get(1)); System.out.println(list.get(2)); // 一次性获取多个集合中的数据 遍历 for(Object obj : list){ System.out.println(obj); } } }

    • 但是实际开发中不建议存储多种类型。所以我们需要使用 泛型来约束集合中存储的类型。

    • 泛型:

      • 可以使用在 接口、类、方法、集合中。本次主要讲解集合中使用泛型。
      • 最用:就是规定集合中存储的类型
      • 使用方式 <类型>;

package day02._07_gather; import Java.util.ArrayList; import Java.util.List; /** * 泛型 */ public class _02_Generic { public static void main(String[] args) { List list = new ArrayList<>(); list.add(1); list.add(5); list.add(3); for (Integer i : list) { System.out.println(i); } } }

    • Set:(集合)

      • 我们最常用的 Set 集合子类是 HashSet。他的底层是 hash 表 + 双链表结构 + 红黑树。

      • 特点:无序且唯一。

      • 案例

package day02._07_gather; import Java.util.HashSet; import Java.util.Set; /** * Set 集合 * HashSet 子类。 */ public class _03_Set { public static void main(String[] args) { Set set = new HashSet<>(); set.add(「Hello」); set.add(「Java」); set.add(「Python」); // 遍历来获取 Set 集合中的数据。 // Set 集合是无序的,所以不能使用普通 for 循环。 // 老办法使用迭代器。 // Iterator iterator = set.iterator(); // while (iterator.hasNext()) { // 是否有下一个元素 // System.out.println(iterator.next()); // 拿到下一个元素 // } // 也可以使用增强 for 循环。 for(String str : set){ System.out.println(str); } } }

    • Map:(映射)

      • Key --> Value 键值对的形式存在。 使用 Key 映射 Value。
      • 我们最常用的是 HashMap。 底层 哈希表。
      • 特点双列集合。双列对应的就是 Key Value。
      • Key 是不能重复的, Value 可以重复。Key 若重复后面的值会覆盖前面的值。
相关推荐
青云计划7 小时前
知光项目知文发布模块
java·后端·spring·mybatis
Victor3567 小时前
MongoDB(9)什么是MongoDB的副本集(Replica Set)?
后端
Victor3567 小时前
MongoDB(8)什么是聚合(Aggregation)?
后端
yeyeye1119 小时前
Spring Cloud Data Flow 简介
后端·spring·spring cloud
Tony Bai9 小时前
告别 Flaky Tests:Go 官方拟引入 testing/nettest,重塑内存网络测试标准
开发语言·网络·后端·golang·php
+VX:Fegn089510 小时前
计算机毕业设计|基于springboot + vue鲜花商城系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
程序猿阿伟10 小时前
《GraphQL批处理与全局缓存共享的底层逻辑》
后端·缓存·graphql
小小张说故事10 小时前
SQLAlchemy 技术入门指南
后端·python
识君啊10 小时前
SpringBoot 事务管理解析 - @Transactional 的正确用法与常见坑
java·数据库·spring boot·后端
想用offer打牌11 小时前
MCP (Model Context Protocol) 技术理解 - 第五篇
人工智能·后端·mcp