第4章 面向对象编程-上

第4章、面向对象编程-上

学习面向对象内容的三条主线:

  1. \(Java\)类及类的成员:属性、方法、构造器;代码块、内部类(\(Java\)两大要素:类、对象)
  2. 面向对象的三大特征:封装性、继承性、多态性(、抽象性)(关注对应代码落地)
  3. 其他关键字:\(this\)\(super\)\(static\)\(final\)\(abstract\)\(interface\)\(package\)\(import\)

目录

  1. 一、面向过程与面向对象
  2. 二、Java 基本元素:类和对象
  3. 三、对象的创建和使用
  4. 四、类的成员之一:属性
  5. 五、类的成员之二:方法
  6. 六、再谈方法
  7. 七、OOP 特征之一:封装与隐藏
  8. 八、类的成员之三:构造器(构造方法,constructor)
  9. 扩展:JavaBean
  10. 扩展:UML 类图
  11. 九、关键字:this
  12. 十、关键字:package、import
  13. 每日一考(构造器、this、package、import)
  14. 接下来是:项目二

一、面向过程与面向对象

  1. 面向过程(\(POP:\)\(Procedure\) \(Oriented\) \(Programming\))与面向对象(\(OOP:\)\(Object\) \(Oriented\) \(Programming\)

    • 二者都是一种思想,面向对象是相对于面向过程而言的。

      • 面向过程,强调的是功能行为,以函数为最小单位,考虑怎么做
      • 面向对象,将功能封装进对象,强调具备了功能的对象,以类/对象为最小单位,考虑谁来做
    • 举例:人把大象装进冰箱

      • 面向过程:①把冰箱门打开;②抬起大象,塞进冰箱;③把冰箱门关闭

      • 面向对象:

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        人{ 
        打开(冰箱){
        冰箱.开门();
        }

        抬起(大象){
        大象.进入(冰箱);
        }

        关闭(冰箱){
        冰箱.关门();
        }
        }

        冰箱{
        开门(){...}
        关门(){...}
        }

        大象{
        进入(冰箱) {...}
        }
  2. 面向对象的三大特征

    • 封装(\(Encapsulation\)
    • 继承(\(Inheritance\)
    • 多态(\(Polymorphism\)
  3. 面向对象的思想概述

    • 程序员从面向过程的执行者转化为了面向对象的指挥者
    • 面向对象分析方法分析问题的思路和步骤
      • 根据问题需要,选择问题所针对的现实世界中的实体
      • 从实体中寻找解决问题相关的属性和功能,这些属性和功能就形成了概念世界中的类
      • 把抽象的实体用计算机语言进行描述,形成计算机世界中类的定义,即借助某种程序语言,把类构造成计算机能够识别和处理的数据结构
      • 将类实例化成计算机世界中的对象,对象是计算机世界中解决问题的最终工具

二、\(Java\)基本元素:类和对象

  1. 面向对象的思想概述

    • 类(\(Class\))和对象(\(Object\))是面向对象的核心概念
      • 类是对一类事物的描述,是抽象的、概念上的定义。例如水果、花、人,其在代码上的体现类似于\(int\)\(char\)\(String\)
      • 对象是实际存在的该事物的个体,也被称为实例(\(Instance\))。例如苹果、玫瑰花、某个具体的人,在代码上的体现类似于某个数据类型声明的变量。
      • 面向对象程序设计的重点是类的设计;类的设计,其实就是类的成员的设计
    • “万事万物皆对象”
      • Java语言范畴中,我们都将功能、结构等封装到类中,通过类的实例化,来调用具体的功能结构
        • Scanner、String等
        • 文件,File
        • 网络资源,URL
      • 涉及到Java语言与前端Html、后端数据库交互时,前后端的结构在Java层面交互时都体现为类和对象
  2. \(Java\)类及类的成员

    • Java代码世界是由诸多个不同功能的类构成的
    • Java中常见的类成员有:
      • 属性 = 成员变量 = field = 域、字段,对应类中的成员变量
      • 方法 = 成员方法 = 函数 = method,对应类中的成员方法

三、对象的创建和使用

  1. 对象创建:类名 对象名 = new 类名();

    • 创建类的对象 = 类的实例化 = 实例化类
  2. 类和对象的使用(面向对象思想落地的实现)

    • 创建类,设计类的成员
    • 创建类的对象
    • 通过"对象.属性""对象.方法"调用对象的结构
  3. 如果创建了一个类的多个对象,则每个对象都独立的拥有一套类的属性(非static),修改其中一个对象的属性不影响另一个对象的属性值。

  4. 对象的内存解析

对象的内存解析

内存解析的说明:引用数据类型的变量只可能存两类值:null 或 地址值(含变量的类型)

四、类的成员之一:属性

  • 属性(成员变量)VS 局部变量
    • 相同点
      • 定义格式:数据类型 变量名 = 变量值;
      • 先声明后使用
      • 都有其对应的作用域
    • 不同点
      • 在类中声明的位置不同:
        • 属性直接定义在类的一对{}中、方法体外;
        • 局部变量是声明在方法内、方法形参、代码块内、构造器形参、构造器内部的变量。
      • 权限修饰符不同:
        • 属性:可在声明属性时,指明其权限、使用权限修饰符(常见修饰符:private、public、缺省、protected)
        • 局部变量:不可使用权限修饰符,只能用final(其权限可由方法修饰符体现)
      • 默认初始化值
        • 属性:根据其类型,都有其初始化值
          整形(byte、short、int、long):0
          浮点型(float、double):0.0
          字符型(char):0或'000'
          布尔型(boolean):false
          引用数据类型(类、接口、数组):null
        • 局部变量:没有默认初始化值,在调用局部变量前必须要显式赋值(特别的,形参在调用时赋值即可)。
      • 在内存中加载的位置
        • 属性:加载到堆空间中(非static)
        • 局部变量:加载到栈空间

五、类的成员之二:方法

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

    • 方法的声明:

      1
      2
      3
      权限修饰符 返回值类型 方法名([形参列表]){
      方法体
      }
    • 说明

      • 权限修饰符:private、public、缺省、protected
      • 返回值类型:有返回值 VS 无返回值
        • 如方法有返回值,则必须在方法声明时,指定返回值类型。同时,方法中,需要使用return关键字来返回指定类型的变量或常量
        • 如方法无返回值,则方法声明时使用void来表示。无返回值的方法中无需使用return,但可使用“return;”结束方法。(return后不能直接声明其他语句)
      • 方法名:标识符,遵循标识符的命名规则和规范,“见名知意”
      • 形参列表:
        • 方法可定义0个、1个或多个形参
        • 格式:数据类型1 形参1, 数据类型2 形参2, ...
      • 方法体:方法功能的体现。
    • 方法的使用中,可调用当前类的属性和方法。方法中不能定义方法

  • 练习

    1. 编写教师类和学生类,并通过测试类创建对象进行测试。
    2. 创建一个Person类,其定义如下:要求(1)创建Person类的对象,设置该对象的name、age、sex属性,调用study方法,输出字符串"studying",调用showAge()方法显示age值,调用addAge()方法给对象的age属性增加2岁;(2)创建第二个对象,执行上述操作,体会同一个类的不同对象之间的关系
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    public class PersonTest { //测试类

    public static void main(String[] args){
    //构造Person类的对象
    Person p1 = new Person();

    //调用对象的结构:属性和方法
    //调用属性:“对象.属性”
    p1.name = "tom";
    p1.age = 18;
    p1.sex = 1;

    //调用方法:“对象.方法”
    p1.study();
    p1.showAge();
    System.out.println(p1.addAge(2));

    Person p2 = new Person();
    p2.name = "sam";
    p2.age = 12;
    p2.sex = 0;

    //调用方法:“对象.方法”
    p2.study();
    p2.showAge();
    System.out.println(p2.addAge(-2));

    }
    }

    class Person { //Person类
    String name;
    int age;
    /**
    * sex: 0 - Female; 1 - Male;
    */
    int sex;

    public void study(){
    System.out.println("studying");
    }

    public void showAge(){
    System.out.println(age);
    }

    public int addAge(int i){
    age += i;
    return age;
    }
    }
    1. 利用面向对象的编程方法,设计类Circle计算圆的面积。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    public class CircleTest {
    public static void main(String[] args){
    Circle c1 = new Circle();
    c1.radius = 10;
    System.out.println(c1.area());
    }
    }
    class Circle{

    double radius;

    public double area(){
    return Math.PI * radius * radius;
    }

    }
    1. 编写程序,声明一个method方法,在方法中打印一个10*8的*型矩阵,在main方法中调用该方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public class Exer3 {
    public static void main(String[] args){
    Exer3 m = new Exer3();
    m.method();
    }

    public void method(){
    for(int i=0; i<10; i++){
    for(int j=0; j<8; j++)
    System.out.print("* ");
    System.out.println();
    }
    }
    }

    1. 修改上一个程序,在method方法中,除打印10*8的*型矩阵外,再计算该矩形的面积,并将其作为方法返回值。在main方法中调用该方法,接收返回的面积值并打印。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    public class Exer3 {
    public static void main(String[] args){
    Exer3 m = new Exer3();
    int area = m.method();
    System.out.println("面积为:"+ area);
    }

    public int method(){
    for(int i=0; i<10; i++){
    for(int j=0; j<8; j++)
    System.out.print("* ");
    System.out.println();
    }
    return 10*8;
    }
    }

    1. 修改上一个程序,在method方法提供m和n两个参数,方法中打印m*n的*型矩阵,并计算该矩阵的面积,将其作为方法返回值。在main方法中调用该方法,接收返回的面积值并打印。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    public class Exer3 {
    public static void main(String[] args){
    Exer3 m = new Exer3();
    int area = m.method(2, 10);
    System.out.println("面积为:"+ area);
    }

    public int method(int m, int n){
    for(int i=0; i<m; i++){
    for(int j=0; j<n; j++)
    System.out.print("* ");
    System.out.println();
    }
    return m*n;
    }
    }

    1. 对象数组题目:定义类Student,包含3个属性:学号number(int),年级state(int),成绩score(int),创建20个学生对象,学号为1到20,年级和成绩由随机数确定。
      • 问题1:打印出3年级(state为3)的学生信息
      • 问题2:使用冒泡排序按学生成绩排序,并遍历所有学生信息
      • 提示:
        • 生成随机数:Math.random();返回值为double类型
        • 四舍五入取整:Math.round(double d);返回值为long类型
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
     public class Student {
    public static void main(String[] args){
    //此处只是开辟一块20个Student类型的对象数组空间,该空间的首地址值赋值给数组名stu
    //定义对象数组后,每个数组元素初始值为null。
    //如不为每个元素初始化将会在后面调用时产生NullPointerException异常
    Student[] stu = new Student[20];
    for(int i=0; i<stu.length; i++){
    //数组元素的类型为Student,故初始化时使用new Student()分配内存空间
    //并将空间的地址赋值给元素
    //String、int等类型无需new,是因为数组元素为基本数据类型或可以直接赋值(地址传递),
    //如String s = "15sadw";(字符串常量或变量传递给字符串数组元素是地址传递)
    //int类型数组元素的值是直接存在堆的相应位置的,无需再次分配空间
    //分配内存空间就要使用 new关键字,并且返回空间的首地址值
    //而自定义的类声明的对象也可进行地址传递,但需要先new一个该类型的变量然后再地址传递,
    //也可直接开辟一块内存空间(new Student()),并将该空间首地址值赋给数组元素
    stu[i] = new Student();
    stu[i].setNumber(i+1);
    stu[i].setState((int)Math.round((Math.random()*5)));
    stu[i].setScore((int)Math.round((Math.random()*100)));
    }

    //遍历输出
    System.out.println("初始化:");
    for(int i=0; i<stu.length; i++){
    System.out.println(stu[i].getNumber() + "\tis @ grade_" + stu[i].getState() + ", score is " + stu[i].getScore());
    }

    //输出年级为3的学生信息
    System.out.println("3年级学生信息:");
    for(int i=0; i<stu.length; i++){
    if(stu[i].getState() == 3)
    System.out.println(stu[i].getNumber() + "\tis @ grade_" + stu[i].getState() + ", score is " + stu[i].getScore());
    }

    //冒泡排序
    for(int i=0; i<stu.length; i++){
    for(int j=0; j<stu.length-i-1; j++){
    if(stu[j].getScore() > stu[j+1].getScore()){
    Student temp = new Student();
    temp = stu[j];
    stu[j] = stu[j+1];
    stu[j+1] = temp;
    }
    }
    }

    //遍历输出
    System.out.println("排完序后:");
    for(int i=0; i<stu.length; i++){
    System.out.println(stu[i].getNumber() + "\tis @ grade_" + stu[i].getState() + ", score is " + stu[i].getScore());
    }
    }

    /**
    * 学号, int型
    */
    int number;
    /**
    * 年级, int型
    */
    int state;
    /**
    * 分数, int型
    */
    int score;

    /**
    *
    * @Description 获得学生的分数
    * @author Hunter Wu
    * @date 2020年10月16日下午4:40:40
    * @return int型 分数
    */
    public int getScore(){
    return score;
    }

    /**
    *
    * @Description 获得学生的学号
    * @author Hunter Wu
    * @date 2020年10月16日下午4:40:58
    * @return int型 学号
    */
    public int getNumber(){
    return number;
    }

    /**
    *
    * @Description 获得学生的年级
    * @author Hunter Wu
    * @date 2020年10月16日下午4:42:02
    * @return int型 年级
    */
    public int getState(){
    return state;
    }

    /**
    *
    * @Description 设置学生的成绩
    * @author Hunter Wu
    * @date 2020年10月16日下午4:51:16
    * @param score
    */
    public void setScore(int score){
    this.score = score;
    }

    /**
    *
    * @Description 设置学生的学号
    * @author Hunter Wu
    * @date 2020年10月16日下午4:50:57
    * @param number
    */
    public void setNumber(int number){
    this.number = number;
    }

    /**
    *
    * @Description 设置学生的年级
    * @author Hunter Wu
    * @date 2020年10月16日下午4:51:31
    * @param state
    */
    public void setState(int state){
    this.state = state;
    }

    }
  • 每日一考

  1. 面向对象思想编程内容的三条主线分别是什么

    • \(Java\)类及类的成员:属性、方法、构造器、代码块、内部类
    • 面向对象三大特征:封装性、继承性、多态性(,抽象性)
    • 其他关键字:\(this\)\(super\)\(static\)\(final\)\(abstract\)\(interface\)\(package\)\(import\)
  2. 面向对象的编程思想?【面试】

  3. 谈谈你对面向对象中类和对象的理解,并指出二者的关系
    面试中,先进行一些描述,然后再举出一些例子,但是举的例子应为开发场景中的例子(比如我们和控制台交互需要提供一个类,这个API给我们提供好了叫做Scanner类,这是类的概念。我们真正执行的时候需要一个Scanner对象,然后通过这个对象来调用他所定义的功能方法,去完成与控制台的交互)

    • 类:抽象的、概念上的内容
    • 对象:实实在在存在的一个实体
    • 对象是由类派生出来的(new出来的)
  4. 面向对象思想的体现一:类和对象的创建和执行操作有那三步?

    • 创建类
    • 类的实例化
    • 调用对象的结构:“对象.属性”、“对象.方法”
  5. 类的方法内是否可以定义变量?是否可以调用属性?是否可以定义方法?是否可以调用方法?

    是,是,否,是

补:JVM内存结构

  • 编译完源程序后,生成一个或多个字节码文件。我们使用JVM中的类的加载器和解释器对生成的字节码文件进行解释运行。意味着,需要将字节码文件对应的类加载到内存中,涉及到内存解析
JVM内存结构
  • 各个结构
    • 虚拟机栈即为平时提到的栈结构。将局部变量存放在栈结构中
    • 堆,将new出来的结构(如数组、对象)加载在堆空间中。补充:对象的属性(非static)加载在堆空间中
    • 方法区:类的加载信息(方法、代码块等)、常量池、静态域(static)
    • 本地方法栈:调用本地C/C++时使用

补:匿名对象

  1. 创建的对象没有显式的赋给一个变量名,即为匿名对象

  2. 特征:一个匿名对象只能使用一次。

  3. 使用:无需另外定义一个变量即可创建一个对象并使用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    public class Exer_2_1 {
    public static void main(String[] args){
    Phone p = new Phone();
    System.out.println(p);

    p.sendEmail();
    p.playGame();

    //匿名对象
    new Phone().price = 1999;
    new Phone().showPrice();

    //匿名对象的使用
    PhoneMall mall = new PhoneMall();
    mall.show(new Phone());
    }
    }


    class PhoneMall{
    public void show(Phone phone){
    phone.sendEmail();
    phone.playGame();
    }

    }

    class Phone{
    double price;

    public void sendEmail(){

    }

    public void playGame(){

    }

    public void showPrice(){
    System.out.println("手机价格为:" + price);
    }
    }

六、再谈方法

  1. 方法的重载(overload)

    • 重载的概念
      • 在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者类型不同即可。
    • 重载的特点:
      • 与返回值类型无关,只看参数列表,且参数列表必须不同。(参数个数或参数类型)。调用时,根据方法参数列表的不同来区别。
      • 两同一不同:同一个类、相同方法名;参数列表不同:参数个数或参数类型或不同类型的参数顺序不同
      • 跟方法的权限修饰符、返回值类型、形参变量名、方法体都没有关系
    • 重载示例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    //返回两个整数的和
    int add(int x, int y){
    return x+y;
    }

    //返回三个整数的和
    int add(int x, int y, int z){
    return x+y+z;
    }

    //返回两个小数的和
    double add(double x, double y){
    return x+y;
    }
    • 在通过对象调用方法时,如何确定某一个指定的方法:方法名-->参数列表
  2. 可变形参的方法

    • 定义:JavaSE5.0中提供了Varargs(variable number of arguments)机制,允许直接定义能和多个实参相匹配的形参。从而可以用一种更简单的方式,来传递个数可变的实参。
    • 使用:
      • 格式:数据类型 ... 变量名
      • 当调用可变个数形参的方法时,传入的参数个数可以是0个、1个、2个...
      • 可变个数形参的方法与本类中其他的方法名相同、形参不同的方法构成重载
      • 可变个数形参的方法与本类中其他的方法名相同、形参相同的方法不构成重载。(5.0前使用数组传入多个参数(String[] args);5.0后使用...表示可变个数参数(String ... args),在形参变量的使用上和数组使用方式相同)
      • 可变个数形参在方法的形参中,必须声明在末尾(防止编译器分不清参数该传给谁)
      • 可变个数形参在方法的形参中,最多只能声明一个可变形参
  3. 方法参数的值传递机制(难重点)

    • 变量赋值:传递的是栈空间的值
      • 如变量是基本数据类型,则赋值的是变量所保存的数据值
      • 如变量是引用数据类型,则赋值的是变量所保存的数据地址值
    • 形参与实参
      • 形参:方法定义时,声明的小括号内的参数
      • 实参:方法调用时,实际传递给形参的数据
    • 方法形参的传递机制:值传递(不是引用传递)
      • 如参数是基本数据类型,则实参赋给形参的值是实参所保存的数据值
      • 如参数是引用数据类型,则实参赋给形参的值是实参所保存的数据地址值
  4. 递归方法

    • 定义:一个方法体内调用它本身
  5. 每日一考

    • 什么是方法的重载
      • 两同一不同
    • 说明Java方法中的参数传递机制的具体体现
      • 如参数为基本数据类型,则传递的是...
      • 如参数是引用数据类型,则传递的是...
    • 成员变量和局部变量在声明的位置上、是否有默认初始化值上、是否能有权限修饰符修饰上、内存分配的位置上有何不同
      • 成员变量声明在类中,有默认初始化值,可有权限修饰符,内存分配在堆中
      • 局部变量声明在方法中,无默认初始化值,不可有权限修饰符,内存分配在栈中
    • 谈谈return关键字的使用
      • 返回方法执行结果
      • 结束方法执行
  6. 面试题

    • 方法的重载与重写的区别?
    • throws  throw
    • String  StringBuffer StringBuilder
    • Collection  Collections
    • final  finally
    • ...相似的概念或类及方法及时总结

七、\(OOP\)特征之一:封装与隐藏

  1. 为什么要封装和隐藏?其作用和含义是什么?
    • 我们程序设计追求“高内聚,低耦合”。
      • 高内聚 :类的内部数据操作细节自己完成,不允许外部干涉;
      • 低耦合 :仅对外暴露少量的方法用于使用。
    • 隐藏对象内部的复杂性,只外公开简单接口。便于外界调用从而提高系统的可扩展性、可维护性。通俗的说,把该隐藏的隐藏起来,该暴露的暴露出来。 这就是封装性的设计思想
  2. 问题的引入:
    • 当我们创建一个类的对象后,我们可以通过"对象.属性"的方式,对对象的属性进行赋值。这里,赋值操作要受到属性的数据类型和存储范围的制约,但是除此之外,没有其他制约条件。而在实际问题中,我们往往需要给属性赋值加入额外的限制条件(实际问题的逻辑限制),这个条件不能在属性声明时体现,我们只能通过属性所在类中的方法进行限制条件的添加。
    • 同时,我们需要避免用户再使用"对象.属性"的方式对属性进行无逻辑限制的赋值,因此需要将属性声明为私有的(private)
    • 以上针对属性就体现了封装性
  3. 封装性的体现(不等同于封装性,只是封装性的一个体现)
    • 我们将类的属性私有化(private),同时,提供公共(public)的方法来获取(getXxx)和设置(setXxx)此属性的值
  4. 封装性的其他体现:① 如上3;②不对外暴露的私有方法;③ 单例模式;④ 如果不希望类在包外被调用,可将类设置为缺省的。
  5. 封装性的体现,需要权限修饰符来配合
    • Java规定了4种权限修饰符(从小到大):private、缺省、protected、public;四种范围:类内、同一个包内、不同包的字类内、同一工程内 4种权限修饰符
    • 4种权限可以用来修饰类及类的内部结构:属性、方法、构造器、内部类
      • 修饰类的话:只能使用缺省、public【问题:public类可在同一工程中访问,那为什么不同包中重名的类可以同时存在。解答:因为权限修饰符只是表明可见性的大小,调用不同的类可以用包名去区别,public只是表明可以在工程中的任意位置调用,并不限制同名是否可以存在】
  6. 总结封装性:Java提供了4种权限修饰符来修饰类及类的内部结构,体现类及类的内部结构在被调用时的可见性的大小

八、类的成员之三:构造器(构造方法,constructor)

  1. 构造器的作用(只要造对象就要用构造器)
    • 创建对象
    • 初始化对象的信息(属性或方法)
  2. 构造器使用说明
    • 如果没有显式的定义类的构造器的话,则系统默认提供一个空参的构造器(该构造器权限和类的权限是相同的)(一个类中一定有构造器)
    • 定义构造器的格式:权限修饰符 类名(形参列表) { }
    • 一个类中定义的多个构造器,彼此构成重载
    • 一旦显式的定义了类的构造器,系统就不再提供默认的空参构造器
    • 一个类中至少会有一个构造器
  3. 构造器与方法有一定的区别:构造器是用来创建对象的;而方法是由对象进行调用的
  4. 属性的赋值过程,赋值顺序为① - ② - ③ - ④,其中① - ② - ③是在对象实例出前执行,只执行一次,而④是可以重复多次执行的
    • ① 默认初始化值
    • ② 显式初始化
    • ③ 构造器中初始化
    • ④ 通过“对象.属性”或“对象.方法”进行复制

扩展:JavaBean

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

  1. 定义:
    • 所谓JavaBean是值符合如下标准的Java类:
      • 类是公共的
      • 有一个无参的公共的构造器
      • 有属性,且有对应的set和get方法

扩展:UML类图

UML类图

九、关键字:\(this\)

  • this的使用:可用来调用属性、方法、构造器
    • 其中,this可理解为当前对象(针对方法) 或 当前正在创建的对象(针对构造器)
      • 在类的方法中,可使用“this.属性”或“this.方法”的方式调用当前对象的属性或方法。但是,在通常情况下,我们都省略“this.”。在特殊情况下:例如方法或构造器的形参和类的属性同名时,我们必须显式的使用“this.属性”的方式表明此变量是属性,而非形参。
      • 在类的构造器中,可使用“this.属性”或“this.方法”的方式调用当前正在创建的对象的属性或方法。但是,在通常情况下,我们都省略“this.”。在特殊情况下:例如构造器的形参和类的属性同名时,我们必须显式的使用“this.属性”的方式表明此变量是属性,而非形参。
    • this调用构造器的用法
      • 在类的构造器中,可显式的使用“this(形参列表)”方式,调用本类中指定的其他构造器
      • 构造器中不能通过“this(形参列表)”的方式调用自己
      • 如果一个类中有n个构造器,则最多有n-1构造器中使用了“this(形参列表)”
      • 规定:“this(形参列表)”必须声明在当前构造器的首行
      • 构造器内部,最多只能声明一个“this(形参列表)”用来调用其他的构造器

十、关键字:\(package\)\(import\)

  1. package关键字的使用
    • 为了更好的实现项目中类的管理,提供了包的概念
    • 使用package声明类或接口所属的包,声明在源文件中的首行
    • 包属于标识符,遵循标识符的命名规则(见名知意)、规范(小写)
    • 每“.”一次,就代表一层文件目录
    • 补充:同一个包下,不可以命名同名的接口、类;不同包下可命名同名的接口或类
    • JDK中主要的包介绍 JDK中主要的包
  2. MVC设计模式 MVC设计模式
  3. import关键字的使用
    • 在源文件中显式的使用import结构导入指定包下的类或接口
    • 声明位置:在源文件中的包声明和类声明之间
    • 如需导入多个结构,则并列写出即可;
    • 可使用xxx.*的方式导入xxx包下的所有结构(类或接口)
    • 如果使用的类或接口是java.lang包下的,则可省略import结构
    • 如果使用的类或接口是本包下的,则可省略import结构
    • 如果在源文件中,使用了不同包下的两个同名类,则必须至少有一个需要以全类名的方式(xxx.xxxx.xx.类名)调用
    • 使用“xxx.*”的方式可以调用xxx包下的所有结构,但如果使用的是xxx子包下的结构则仍需显式使用“xxx.子包”结构导入
    • import static 可以导入指定类或接口的静态结构(属性或方法)

每日一考(构造器、this、package、import)

  1. 构造器的作用是什么?使用中有哪些注意点(>= 3条)
    • 作用:创建对象、初始化对象信息
    • 注意点:
      • 当没有显式声明构造器时,类会提供了一个默认的无参构造器
      • 一个类中定义的多个构造器,彼此构成重载
      • 一旦显式的定义了类的构造器,系统就不再提供默认的空参构造器
  2. 关于类的属性的赋值,有几种赋值的方式。谈谈赋值的先后顺序
    • ① 默认值
    • ② 显式初始化
    • ③ 构造器初始化
    • ④ 通过“对象.属性”“对象.方法”的方式赋值
    • 先后顺序是:① - ② - ③ - ④
  3. this关键字可用来调用那些结构,简单说明一下其使用
    • this可用来调用属性、方法、构造器
    • this代表的是 当前使用的对象 或 正在创建的对象。使用“this.属性”或“this.方法”的方式调用正在使用对象中的属性或方法。使用“this(形参列表)”方式调用与其形参列表匹配的构造函数
  4. java中目前学习涉及到的四种权限修饰符都有什么?并说明各自的权限范围
    • private、缺省、protected、public
    • private仅能在同一个类中可见
    • 缺省仅能在同一个类或同一包下可见
    • protected仅能在同一个类、同一包、不同包下的子类中可见
    • public可在同一个类、同一包、不同包下的子类、同一工程中可见

接下来是:项目二