第一章:面向对象思想概述

1.1 概述

  • Java 语言是一种面向对象的程序设计语言,面向对象思想( OOP )是一种程序设计思想,我们在面向对象思想的指引下,使用 Java 语言去设计、开发计算机程序。
  • 这里的 对象 泛指现实中的一切事物,每种事务都具备自己的 属性行为
  • 面向对象思想就是在计算机程度设计的过程中,参照现实中的事物,将事物的属性特征、行为特征抽象出来,描述成计算机事物的设计思想。
  • 面向对象思想区别于面向过程思想( POP ),强调的是通过调用对象的行为来实现功能,而不是自己一步一步的去操作实现。

1.2 面向过程和面向对象的区别

  • 面向过程( POP ):Process Oriented Programming
    • 以函数(方法)为最小单位。
    • 数据独立于函数之外。
    • 以过程、步骤为主,考虑怎么做?
  • 面向对象( OOP ):Object Oriented Programming
    • 以类、对象为最小单位。
    • 类包括数据和方法。
    • 以对象(谁)为主,考虑谁来做,谁能做?
  • 面向对象依然包含面向过程,只不过关注点变了,关注谁来做。
  • 面向过程中程序员的角色:程序员是具体执行者。
  • 面向对象中程序员的角色:程序员是指挥者。
  • 面向对象思想是一种更符合我们思考习惯的思想,它可以将复杂的事情简单化,并将我们从执行者变成了指挥者。

1.3 面向对象的基本特征

  • 面向对象的语言中,包含了三大基本特征:封装继承多态

第二章:类和对象

2.1 概述

  • 环顾周围,我们会发现很多对象,比如:桌子、椅子、电脑、同事、同学等。桌子属于办公用品,同事和同学都是人类,那么什么是类?什么是对象?

2.2 什么是类?

  • 类是一类具有相同特性的事物的抽象描述,是一组相关 **属性****行为** 的集合。可以将类看成是一类事物的模板,使用事物的 属性特性行为特性 来描述该类事物。
  • 类可以看做是一个模板,或者图纸,系统根据类的定义来创建对象,以后我们要造一个汽车,怎么造?类就是这个图纸,规定了汽车的详细信息,然后根据图纸将汽车造出来。

image.png

2.3 什么是对象?

  • 对象:就是一类事物的具体个体。因此对象也称之为类的一个 **实例** (instance)
  • 万物万事皆对象

image.png
image.png

2.4 类和对象的关系

  • 类是对一类事物的描述,是 抽象的
  • 对象是一类事物的实例,是 具体的
  • 类是对象的模板,对象是类的实体

image.png

第三章:类的设计

3.1 事物和类的对比

  • 现实世界中的一类事物:
    • 属性 :事物的状态信息。
    • 行为 :事物能够做什么。

image.png

  • Java中用 class 描述事物也是如此:
    • 成员变量 :对应事物的 属性
    • 成员方法 :对应事物的 行为

3.2 类的定义

  • 属性:在类中通过成员变量来体现(类中方法外的变量,和以前相比位置发生了变化)
  • 行为:在类中通过成员方法来体现(和前面的方法相比去掉static关键字即可)

  • 语法: ```java 访问修饰符 class 类名 {

    1. // 成员变量
    2. 访问修饰符 数据类型 属性名 = 初始化值;
    3. 访问修饰符 数据类型 属性名;
    4. // 成员方法
    5. 方法1;
    6. 方法2;

    }

![image.png](https://cdn.nlark.com/yuque/0/2022/png/26775128/1649046960851-3141d93e-b155-40ac-b246-084881a05508.png#clientId=u0128812a-76fe-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=424&id=ub55a92c0&margin=%5Bobject%20Object%5D&name=image.png&originHeight=530&originWidth=1362&originalType=binary&ratio=1&rotation=0&showTitle=false&size=52469&status=done&style=stroke&taskId=u7623af5d-9c25-470a-bb16-7cd922d7a57&title=&width=1089.6)

<a name="pXAod"></a>
## 3.3 成员变量
<a name="q3QY8"></a>
### 3.3.1 概述

- **类中方法外的变量,和以前相比位置发生了变化,可以用访问修饰符**
```java
访问修饰符 class 类名{
    访问修饰符 数据类2始化值;
    访问修饰符 数据类型 属性名;
}
  • 访问修饰符:
    • 常用的权限访问修饰符有:private 、缺省 、protected 、public 。
    • 其他的访问修饰符:static 、final 。
  • 数据类型:任何基本数据类型或任何引用数据类型。
  • 属性名:属于标识符,符合命名规则和规范即可。

3.3.2 成员变量的默认初始化值

  • 当一个对象被创建后,会对其中各种类型的 成员变量 自动进行初始化赋值。除了基本数据类型之外的变量类型都属于引用数据类型。 | 成员变量类型 | 初始化值 | | —- | —- | | byte、short、int | 0 | | long | 0L | | float | 0.0F | | double | 0.0 | | char | '\\u0000' | | boolean | false | | 引用数据类型(数组,类,接口) | null |

3.3.3 成员变量和局部变量的区别

  • 成员变量:方法体外,类体内声明的变量。
  • 局部变量:在方法体内声明的变量。

image.png

  • 成员变量和局部变量的区别: | | 成员变量 | 局部变量 | | —- | —- | —- | | 声明的位置 | 直接声明在类中,方法体外 | 方法形参或内部,代码块内等 | | 访问修饰符 | private 、public 、static 、final 等 | 不能用权限访问修饰符,可以用 final 修饰 | | 初始化值 | 有默认的初始化值 | 没有默认初始化值,必须先赋值,方可使用;
    注意:形参调用时赋值即可 | | 内存加载位置 | 堆空间或静态域内 | 栈空间 | | 生命周期 | 实例变量随着对象的存在而存在
    类变量随着类的存在而存在 | 随着方法的调用而存在,随着方法的调用完毕而消失 |

3.3.4 成员方法

作用与前面方法基本上都是一样的效果,不过是所属群体的变化

面向对象上 - 图8

第四章:对象的创建和使用

4.1 对象的创建和使用

对象的创建语法:

// 匿名对象
new 类名();
// 给创建的对象命名,或者说,将创建的对象用一个引用数据类型的变量保存起来
类名 对象名 = new 类名();

说明:如果创建了一个类的多个对象,则每个对象都独立拥有一套类的属性(非static的)
这也就意味着,我们修改一个对象的属性a, 不影响另一个对象的属性a

对象的使用语法:

// 赋值
对象名.成员变量 = 值;
// 访问
对象名.成员变量;

示例:

public class StudentTest {
    public static void main(String[] args) {
        // 匿名对象
        System.out.println(new Student());
        // 把创建的对象用一个引用数据类型的变量保存起来
        Student student = new Student();
        System.out.println("student = " + student);

        student.name = "法外狂徒--张三";
        student.age = 18;
        student.gender = '男';

        System.out.println("姓名:" + student.name + ",年龄:" + student.age + ",性别:" + student.gender);

        student.study();
    }
}

4.2 类的访问机制

  • 在一个类中的访问机制 :类中的方法可以直接访问类中的成员变量,但是 static 方法访问非 static 的成员变量,编译不通过。
  • 在不同类中的访问机制 :先创建要访问类的对象,然后用对象访问类中定义的成员。

4.3 匿名对象

  • 可以不定义对象的句柄,而直接调用这个对象的方法,这样的对象就叫做匿名对象。
  • 匿名对象的语法:

    new 类名();
    
  • 应用场景:

    • 如果对一个对象只需要进行一次方法调用,那么就可以使用匿名对象。
    • 实际开发中,经常将匿名对象作为实参传递给一个方法调用。

4.4 对象内存图

一个对象内存图.mp4 一个对象内存图.mp4 (2.43MB)

第五章:关键字 package和import

5.1 分包思想

如果将所有的类文件都放在同一个包下,不利于管理和后期维护,所以,对于不同功能的类文件,可以放在不同的包下进行管理

5.2 package(包)

包的概述

  • 包本质上就是文件夹
  • 多级包之间使用.进行分割,
  • 包名字母通常都是小写,通常使用所在公司域名的倒置,比如:com.github.xxx

包的作用:

  • 包帮助管理大型软件系统:将功能相近的类划分到同一个包中,比如:MVC设计模式
  • 包可以包含类和子包,划分项目层次,便于管理。
  • 解决类命名冲突的问题。
  • 控制访问权限。

包的注意事项

  • package语句必须是程序的第一条可执行的代码
  • package语句在一个java文件中只能有一个
  • 如果没有package , 默认表示无包名
  • 语法:
    //package 语句中,用 . 来指明包(目录)的层次。 
    package 顶层包名.子包名;
    

jdk 中的主要包(类库):

  • java.lang :包含一些 Java 语言的核心类,如 String 、Math 、Integer 、System 和 Thread ,提供常用功能。
  • java.net :包含执行和网络相关的操作的类和接口。
  • java.io :包含能提供多种输入、输出的功能的类。
  • java.util :包含一些实用工具类,如定义系统特性、接口的集合框架类、使用和日期日历相关的函数。
  • java.text :包含了一些 java 格式化相关的类。
  • java.sql :包含了 java 进行 JDBC 数据库编程的相关类/接口。
  • java.awt :包含了构成抽象窗口工具集的多个类,这些类被用来构建和管理应用程序的图形用户界面。

5.3 import(导入)

为了使用定义在不同包中的 Java 类,需要使用 import语句来引入指定包层次下所需要的类或全部类( * )。
●import语句告诉编译器到哪里去寻找类 。
●语法:

import 包名.类名;
  • 注意事项:

    • 在源文件中使用 import 显示的导入指定包下的类或接口。
    • import 声明在 package 声明和 class 声明之间。
    • 如果需要导入多个类或接口,那么就并列的显示多个 import 语句即可。

      import java.util.*;
      
    • 如果导入的类或接口是 java.lang 包下的,或者是当前包下的,则可以省略此 import 语句。

    • 如果在代码中使用不同包下的同名的类,那么就需要使用类的全类名(包名.类名)的方式指定调用的是哪个类。
    • 如果已经导入 java.a 包下的类,那么如果需要使用 a 包的子包下的类,仍然需要导入。
    • import static 组合的使用:调用指定类或接口下的静态的属性或方法。

5.4 访问控制

访问范围 private default protected public
同一类中
同一包中
子类中
全局范围

private(类访问级别):如果类的成员被private修饰,则这个成员只能被该类的其他成员访问,其他类无法直接访问;

default(包访问级别):如果一个类或者类的成员不使用任何访问控制修饰符,则称它为默认访问控制级别,这个类或者类的成员只能被本包中的其他类访问

protected(子类访问控制级别):如果一个类的成员被protected修饰,那么这个成员技能被同一包下的其他类访问,也能被不同包下该类的子类访问
注意:而在不同包中只有在子类中可见,在子类中反而不能通过父类的对象访问父类的protected成员变量和方法。

public:如果一个类或者类的成员被public修饰,那么这个类的成员能被所有的类访问,不管访问类与被访问类时候在同一个包中

六、OOP特征之一:封装

6.1 概述

  • 程序设计追求 高内聚、低耦合
    • 高内聚:类的内部数据操作细节自己完成,不允许外部干涉。
    • 低耦合:仅对外暴露少量的方法用于使用。
  • 封装:隐藏对象内部的复杂性,只对外部公开简单的接口,便于外界调用,从而提高系统的可扩展性、可维护性。换言之,将该隐藏的隐藏起来,该暴露的暴露出来

6.2 为什么要进行封装?

  • 使用者对类内部定义的属性(对象的成员变量)的直接操作会导致数据的错误、混乱或安全性问题。

    public class StudentTest {
     public static void main(String[] args) {
         //创建对象
         Student s = new Student();
         //给成员变量赋值
         s.name = "林青霞";
         s.age = -10;//不合理啊
     }
    }
    

    6.3 Java中的封装

  • Java 中通过将数据声明为私有的( private ),再提供公共的( public )方法:setXxx()getXxx() 来实现对该属性的操作,以实现以下的目的:

  • ① 隐藏一个类中不需要对外提供的实现细节。
  • ② 使用者只能通过事先定制好的 方法来访问数据 ,可以方便的加入控制逻辑,限制对属性的不合理操作。
  • ③ 便于修改,增强代码的维护性。

    public class Animal {
    
     /**
      * 腿 将属性进行私有化
      */
     private int legs;
    
     public int getLegs() {
         return this.legs;
     }
    
     public void setLegs(int legs) {
         if (legs != 0 && legs != 2 && legs != 3) {
             System.out.println("动物的腿一般为0、2、4");
             return;
         }
         this.legs = legs;
     }
    
     /**
      * 吃饭的方法
      */
     public void eat() {
         System.out.println("吃饭");
     }
    
     /**
      * 移动的方法
      */
     public void move() {
         System.out.println("移动");
     }
    }
    
    public class AnimalTest {
     public static void main(String[] args) {
         Animal animal = new Animal();
         // 非法 动物的腿一般为0、2、4
         animal.setLegs(-100);
         System.out.println(animal.getLegs());
         animal.eat();
         animal.move();
     }
    }
    

6.4 练习

  • 创建程序,在其中定义两个类:Student和 StudentDemo。定义如下:用 setAge() 设置人的合法年龄( 0~130 ),用 getAge() 返回人的年龄。用StudentTest类中实例化 Student类的对象 b ,调用 setAge() 和 getAge() 方法,体会 Java 的封装性。

  • /*
      学生类
    */
    class Student {
      //成员变量
      String name;
      private int age;
    
      //提供get/set方法
      public void setAge(int a) {
          if(a<0 || a>120) {
              System.out.println("你给的年龄有误");
          } else {
              age = a;
          }
      }
    
      public int getAge() {
          return age;
      }
    
      //成员方法
      public void show() {
          System.out.println(name + "," + age);
      }
    }
    
    public class StudentTest {
      public static void main(String[] args) {
          //创建对象
          Student s = new Student();
          //给成员变量赋值
          s.name = "林青霞";
          //s.age = -10;//不合理啊
          s.setAge(30);
          //调用show方法
          s.show();
      }
    }
    

    七、关键字 this

7.1 概述

  • 在 Java 中,this 关键字比较难理解,它的作用和其词义比较接近:
    • ① 它在方法内部使用,表示这个方法所属对象的引用。
    • ② 它在构造器内部使用,表示该构造器正在初始化的对象。
  • this 可以调用类的属性、方法和构造器。
  • 当在方法内部需要用到调用该方法的对象是,就需要使用 this ,具体来说,就是用 this 来区分 属性局部变量

    7.2 this调用属性和方法

  • ① 在任意方法或构造器内,如果使用当前类的成员变量或成员方法可以在前面添加 this ,增强程序的阅读性。不过,通常情况下,我们都习惯省略 this 。

  • ② 当形参和成员变量同名的时候,如果在方法内部或构造器内部需要使用成员变量,必须添加 this 来表明该变量是类的成员变量。
  • ③ 使用 this 访问属性和方法时,如果在本类中没有找到,会从父类中查找。

7.3 this内存原理

简单理解:方法被哪个对象调用,this就代表哪个对象

1590938942838.png

1590938969305.png

7.3 this调用本类的构造器

  • this 可以作为一个类中构造器相互调用的特殊格式。 ```java package com.thisdemo2;

/**

  • @author 许大仙
  • @version 1.0
  • @since 2021-09-04 09:18 / public class Person { /*

    • 姓名 */ private String name;

      /**

    • 年龄 */ private int age;

      /**

    • 无参构造器 */ public Person() { System.out.println(“无参构造器”); }

      public Person(String name) { this(); // 调用本类的无参构造器 this.name = name; }

      public Person(String name, int age) { this(name); // 调用一个参数的构造器 this.age = age; }

      /**

    • 获取信息 *
    • @return {@link String} */ public String getInfo() { return “姓名:” + this.name + “,年龄:” + this.age; } } ```

7.4 注意事项

  • ① 可以在类中的构造器中使用 this(形参列表) 的方式,调用本类中重载的其它的构造器。
  • ② 构造器中不能使用 this(形参列表) 的方式调用自身构造器。
  • ③ 如果一个类中声明了 n 个构造器,则最多有 n-1 个构造器中使用了 this(形参列表)
  • this(形参列表) 必须声明在类的构造器的首行。
  • ⑤ 在类的构造器中,最多只能声明一个 this(形参列表)

八、构造方法(构造器)

8.1 概述

是一种特殊的方法,用于构建对象。在对象创建时被调用,对象创建完,方法就执行结束;

8.2 语法

访问修饰符 类名 (参数列表){
    // 初始化语句;
}

注意 :

  • 方法名与类名相同,大小写也要一致
  • 没有返回值类型,连void都没有
  • 构造器不能被 static 、final 、synchronized 、abstract 、native 修饰
  • 没有具体的返回值(不能由retrun带回结果数据)

    8.3 执行时机

  • 创建对象的时候调用,每创建一次对象,就会执行一次构造方法

  • 构造方法在初始化对象时自动执行,一般不能显式地直接调用.

    8.4 构造方法的作用

  • ① 创建对象。

  • ② 给对象进行初始化。
    Order o = new Order();
    Person p = new Person("张三",15);
    

    8.5 构造器的重载

8.5.1 构造器类别

  • 根据参数的不同,构造器可以分为如下两类:
  • ① 隐式无参构造器(系统 默认 提供)。
  • 显式 定义一个或多个构造器(无参、有参)。

8.5.2 构造器重载注意事项

  • ① Java 语言中,每个类都至少有一个构造器。
  • ② 一旦显式的定义了构造器,则系统 不再 提供默认构造器。
  • ③ 一个类可以创建多个 重载 的构造器。
  • ④ 父类的构造器不可以被子类继承。
  • ⑤ 无参构造跟有参构造最好同时提供

示例:

package com.lhl.constructor;

public class Student {
    /*
        格式:
               1. 方法名需要跟类名相同, 大小写也要一致
               2. 没有返回值类型, 连void都没有
               3. 没有具体的返回值(不能由return带回具体的结果)
     */

    private String name;
    private int age;

    // 1. 如果一个类中没有编写任何构造方法, 系统将会提供一个默认的无参数构造方法
    public Student(){}

    // 2. 如果手动编写了构造方法, 系统就不会再提供默认的无参数构造方法了
    public Student(String name, int age){
        this.name = name;
        this.age = age;
        System.out.println("我是Student类的构造方法");
    }

    public void show(){
        System.out.println(name + "..." + age);
    }
}
package com.lhl.constructor;

public class TestStudent {
    public static void main(String[] args) {
        Student stu1 = new Student("张三",23);
        stu1.show();

        Student stu2 = new Student();
    }
}

九、标准类(JavaBean)

9.1 概述

  • JavaBean 是一种 Java 语言编写的可重用组件。
  • 所谓 JavaBean ,是指符合如下标准的 Java 类:
    • 类是公共的
    • 有一个无参的公共的构造器
    • 有属性,且有对应的getter和setter方法
  • 用户可以使用 JavaBean 将功能、处理、值、数据库访问和其他任何可以用 Java 代码创建的对象进行打包,并且其他的开发者可以通过内部的 Jsp 页面、Servlet 、其他 JavaBean 或者应用来使用这些对象。
  • 用户可以认为 JavaBean 提供了一种随时随地的复制和粘贴的功能,而不用关系任何改变。
public class Person {
    /**
     * 名称
     */
    private String name;

    /**
     * 年龄
     */
    private int age;

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return this.age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" + "name='" + this.name + '\'' + ", age=" + this.age + '}';
    }
}