首页 > 编程语言 >Java基础篇(四)(超详细整理,建议收藏!!!)

Java基础篇(四)(超详细整理,建议收藏!!!)

时间:2024-10-31 21:48:17浏览次数:3  
标签:Java 详细 构造方法 int 收藏 对象 数组 方法 变量

目录

 五、数组

5.1  数组的概念

5.2  数组声明

5.3  数组创建与初始化

5.3.1  使用new创建数组

5.3.2  创建数组的三种方式

5.3.3  创建数组需要注意的问题

5.4  数组操作

5.5  数组排序

5.5.1  排序(冒泡)

5.5.2  Arrays.sort() 

5.6   Arrays工具类

5.6.1 排序(sort)

5.6.2 填充(fill)

5.6.3 拷贝(copyOf)

5.6.4 二分查找(binarySearch)

使用二分查找时,必须先将数组排序  ! ! !

5.6.5  判断相等(equals)

5.7  多维数组

5.7.1  二维数组的声明、创建

5.7.2  为二维数组使用初始化器

六、面向对象-类和对象

6.1  类与对象的概念

6.1.1  面向对象的概念

6.1.2  使用类和对象开发程序的基本步骤

6.1.3  类与对象

6.2  定义类

6.2.1  类的一般形式

6.2.2  类的属性

6.2.2  类的方法

6.3  对象的创建于使用

6.3.1  对象的声明与创建

6.3.2  访问对象的成员

6.3.3  为引用变量赋值

6.3.4  对象比较

6.4  构造器/构造方法

6.4.1  构造方法的语法

6.4.2  new运算符

6.4.3  this关键字

6.5  方法深入分析

6.5.1  方法定义

6.5.2  方法调用

6.5.3  参数传递与返回值

6.5.4  return关键字

6.5.5  参数传递的两种方式

6.6  方法重载

6.6.1  方法重载基础

6.6.2  重载构造方法

6.7  static关键字

6.7.1  静态变量

6.7.2  静态方法

6.7.3  关于static的几点说明

七、面向对象-封装

7.1 Java封装的步骤

7.2 包

7.3  访问范围

7.4  访问修饰符与访问控制

八、向对象-继承

8.1  继承基础

8.1.1  继承的概念

8.1.2  继承的语法

8.1.3  成员继承的规则

8.1.4  子类的构造方法

8.1.5  创建多级继承层次 

8.1.6  超类引用变量可以引用子类对象

8.1.7  对象的转型

8.1.8  方法重写介绍

8.1.9  变量隐藏

8.2  super关键字

8.2.1  使用super()调用父类的构造方法

8.2.2  使用super访问父类中被子类隐藏的成员

8.3  Object

8.3.1  Object类介绍

8.3.2  equals()方法与对象相等性比较

8.3.3  重写toString()方法

8.4  final

8.4.1  final修饰变量、方法、类

8.4.2  引用类型的常量


 五、数组

5.1  数组的概念

Java数组是一个包含类似数据类型的元素的对象。 它是一个数据结构,我们存储类似的元素。 只能在java数组中存储固定的元素集合。Java中的数组是基于索引的,数组的第一个元素存储的索引为 0

数组元素的类型:可以是基本类型,也可以是引用类型

int[] nums;  //每个元素是int类型,int就是基本类型

String[]  args  //数组中的每个元素都是String类型,String就是引用类型

5.2  数组声明

两种方式:建议采用第一种方式

dataType[] arrayRefVar;   // 首选的方法
 
或
 
dataType arrayRefVar[];  // 效果相同,但不是首选方法

5.3  数组创建与初始化

5.3.1  使用new创建数组

int[] nums;        //声明数组,并没有创建数组,没有开辟堆内存。

nums = new int[5];  //创建数组,必须设置长度   开辟堆内存

new:用于分配内存的特殊运算符。通过new分配的数组,其元素会被自动初始化为0(对于数值类型)、false(对于boolean类型)或null(对于引用类型)。

说明:

获得一个数组需要两个步骤,第一步是声明,第二步是创建数组对象。

一个数组就是一个对象。数组是动态创建的,所有对象都是动态创建的。

对于引用类型的变量:在内存中有两部分:引用变量 具体的对象

5.3.2  创建数组的三种方式

int[]  nums = new int[5];  //初始化为默认值

int[]  nums = {1,2,3,4,5};  //初始化为{}中指定的值,静态初始化

int[]  nums = new int[] {1,2,3,4,5};//初始化为{}中指定的值  静态初始化

5.3.3  创建数组需要注意的问题

1、创建数组时必须知道数组的长度,否则new不知道要开辟多大的内存

2、第二种方式创建数组,必须在声明数组的同时创建数组

3、创建数组之后,数组的长度不能再改变。

说明:

数组的初始化分为静态初始化和动态初始化,静态初始化在初始化时由程序员显式指定每个数组元素的初始值,由系统决定数组长度。

5.4  数组操作

1、数组排序及元素查找

示例:

import java.util.Arrays;
 
public class MainClass {
    public static void main(String args[]) throws Exception {
        int array[] = { 2, 5, -2, 6, -3, 8, 0, -7, -9, 4 };
        Arrays.sort(array);
        printArray("数组排序结果为", array);
        int index = Arrays.binarySearch(array, 2);
        System.out.println("元素 2  在第 " + index + " 个位置");
    }
    private static void printArray(String message, int array[]) {
        System.out.println(message
        + ": [length: " + array.length + "]");
        for (int i = 0; i < array.length; i++) {
            if(i != 0){
                System.out.print(", ");
            }
            System.out.print(array[i]);
        }
        System.out.println();
    }
}

以上代码运行输出结果为:

数组排序结果为: [length: 10] -9, -7, -3, -2, 0, 2, 4, 5, 6, 8
元素 2 在第 5 个位置

2、通过循环处理数组(打印输出所有数组元素)

示例:

public class TestArray {
   public static void main(String[] args) {
      double[] myList = {1, 3, 2, 5};
 
      // 打印所有数组元素
      for (int i = 0; i < myList.length; i++) {
         System.out.println(myList[i] + " ");
      }
   }
}

以上代码运行输出结果为:

1
3
2
5

3、使用length属性获取数组的长度,从而可以避免数组越界。

示例:

public class Test {
 
    public static void main(String[] args) {
 
        // 定义一个一维数组
 
        int[] numbers = {1, 2, 3, 4, 5};
 
 
        // 获取数组的长度
 
        int length = numbers.length;
 
 
        // 打印数组的长度
 
        System.out.println("数组的长度是: " + length);
 
    }
 
}

以上代码运行输出结果为:

数组的长度是: 5


5.5  数组排序

5.5.1  排序(冒泡)

冒泡排序的基本原理

冒泡排序(Bubble Sort)是一种简单的排序算法,它通过多次遍历待排序的元素,比较相邻元素的大小,并交换它们直到整个序列有序。冒泡排序的基本思想是将较大的元素逐渐“浮”到数组的右端,而较小的元素逐渐“沉”到数组的左端。其基本原理如下:

  1. 从数组的第一个元素开始,比较相邻的两个元素。
  2. 如果前一个元素大于后一个元素(升序排序),则交换它们的位置。
  3. 步骤1和步骤2,直到遍历整个数组。
  4. 上步骤,每次遍历都将最大的元素“冒泡”到数组的末尾。
  5. 复以上步骤,但不包括已排序的最大元素,直到整个数组排序完成。

示例:

import java.util.Arrays;


public class Test{

    public static void main(String[] args) {
        int[] arr = new int[]{5, 7, 4, 3, 6, 2};
        bubbleSort(arr);
        System.out.println("冒泡排序完的数组:" + Arrays.toString(arr));

    }

    public static void bubbleSort(int[] arr) {
        int n = arr.length;
        //外部循环控制排序的趟数。冒泡排序的每一趟会将最大的元素"冒泡"到数组的末尾,因此需要执行 n-1 趟,其中 n 是元素的总数
        for (int i = 0; i < n - 1; i++) {
            //内循环控制每趟比较的次数。由于每一趟都会将一个最大的元素沉到数组末尾,所以内循环次数逐渐减小。
            for (int j = 0; j < n - i - 1; j++) {
                if (arr[j] > arr[j + 1]) {
                    // 交换arr[j]和arr[j+1]
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
            System.out.println("第" + (i + 1) + "趟:" + Arrays.toString(arr));
        }
    }
}

 以上代码运行输出结果为:


第1趟:[5, 4, 3, 6, 2, 7]
第2趟:[4, 3, 5, 2, 6, 7]
第3趟:[3, 4, 2, 5, 6, 7]
第4趟:[3, 2, 4, 5, 6, 7]
第5趟:[2, 3, 4, 5, 6, 7]
冒泡排序完的数组:[2, 3, 4, 5, 6, 7]

5.5.2  Arrays.sort() 

Arrays是Java提供的一个工具类。在Java中我们经常需要对数组进行排序。而对于字符数组来说,我们可以使用Java提供的Arrays类的sort()方法来实现排序操作。

示例:

import java.util.Arrays;

public class Main {

        public static void main(String[] args) {
            // 定义一个字符数组
            char[] charArray = {'b', 'c', 'a', 'e', 'd'};

            // 使用Arrays类的sort()方法对字符数组进行排序
            Arrays.sort(charArray);

            // 打印排序后的结果
            for (char c : charArray) {
                System.out.print(c + " ");
            }
            System.out.println();
        }

}

 以上代码运行输出结果为:

a b c d e 

5.6   Arrays工具类

Arrays类为java.util包里的一个工具类,提供对数组的一些操作方法,常用的有排序(sort)、填充(fill)、拷贝(copyOf)、查找(binarySearch)、判断相等(equals)等。

5.6.1 排序(sort)

Arrays.sort() 支持的类型有char、double、int、byte、float等,同时还支持泛型,但需要自己实现Comparator接口

int ary1[] = new int[]{5,23,15,35,24,6,80,18};
//使用Arrys.sort()对ary1进行从小到大排序
Arrays.sort(ary1);
for (int i : ary1) {
    System.out.print(i+" ");
}

 以上代码运行输出结果为:

5 6 15 18 23 24 35 80 

5.6.2 填充(fill)

将数组所有元素赋值为统一的填充值,如果对应元素已经有值了,则将覆盖原来的值

//Arrays.fill(int[] a, int val) 的实现:
public static void fill(int[] a, int val) {
        for (int i = 0, len = a.length; i < len; i++)
            a[i] = val;
}

对数组ary2进行填充,将所有元素填充为6:

int ary2[] = new int[10];
Arrays.fill(ary2, 6);
for (int i : ary2) {
    System.out.print(i+" ");
}

 以上代码运行输出结果为:

6 6 6 6 6 6 6 6 6 6 

5.6.3 拷贝(copyOf)

参数:  

     int[] original:被拷贝的数组

   int newLength:被拷贝的长度,即original中被拷贝元素的长度

Arrays.copyOf() 函数会返回一个全新的数组,数组中的元素依次被赋值为orignal数组中前n个元素的值,n即被拷贝的长度,当n大于original数组的长度时,可用来对数组长度进行扩展,扩展部分元素值为0

int ary0[] = new int[]{1,2,3,4,5,6};
int ary1[];
//将ary0前三个元素拷贝给ary1
ary1 = Arrays.copyOf(ary0, 3);
//打印ary1的长度与元素值
System.out.println(ary1.length);
for (int i : ary1) {
    System.out.print(i+" ");
}

 以上代码运行输出结果为:

3
1 2 3 

表明ary0中前3个元素【1,2,3】被复制给了一块新的内存空间,同时ary1指向该空间:

5.6.4 二分查找(binarySearch)

     1、使用二分查找时,必须先将数组排序  ! ! !

     2、一般用在查找元素是否存在

    3、如果数组没有排序,结果无法确定

    4、如果包含多个指定值,无法保证找到的是哪一个,如果找不到,则返回负数

int ary0[] = new int[]{1,2,5,4,3,6};
//对ary0中3这个元素进行查找
int index = Arrays.binarySearch(ary0, 3);
System.out.println("未排序的数组为:");
showAry(ary0);
System.out.println("未排序进行查找结果:"+index);
//对ary0进行排序,再次查找
Arrays.sort(ary0);
System.out.println("排序的数组为:");
showAry(ary0);
index = Arrays.binarySearch(ary0, 3);
System.out.println("排序后进行查找结果:"+index);
//ary0指向新的、存在多个相同元素数组
ary0 = new int[]{1,2,3,4,5,2,6,3,8};
//再次进行查找
Arrays.sort(ary0);
System.out.println("多值相同且排序过的数组:");
showAry(ary0);
index = Arrays.binarySearch(ary0, 3);
System.out.println("多值相同进行查找结果:"+index);

 以上代码运行输出结果为:

未排序的数组为:
1 2 5 4 3 6
未排序进行查找结果:-3
排序的数组为:
1 2 3 4 5 6
排序后进行查找结果:2
多值相同且排序过的数组:
1 2 2 3 3 4 5 6 8
多值相同进行查找结果:4

5.6.5  判断相等(equals)

使用Arrays.equals() 判断相等时,进行的是数组各元素的值的比对,而非对ary0和ary1所指向地址的比对,具体实现如下:

public static boolean equals(int[] a, int[] a2) {
        if (a==a2)
            return true;
        if (a==null || a2==null)
            return false;

        int length = a.length;
        if (a2.length != length)
            return false;

        for (int i=0; i<length; i++)
            if (a[i] != a2[i])
                return false;

        return true;
}

 以上代码运行输出结果为:

false
true

5.7  多维数组

5.7.1  二维数组的声明、创建

在Java中,多维数组(multidimensional array)实际上是数组的数组。

下面声明并创建了一个名为twoD的二维数组:

int[][] twoD = new int[4][5];   //4行5列  这种说法是不严谨

twoD是一维数组,但是数组的元素也是一个数组

int[]  表示int类型的数组,即数组元素为int类型

int[][]  表示int[]类型的数组,即数组元素为int[]类型

5.7.2  为二维数组使用初始化器

int[][]  a = new int[3][];

a[0] = new int[]{1,2,3};

a[1] = new int[]{4,-5,6,9,0,8};  //a[1][2]

a[2] = new int[]{7,8};



int[][] nums = {{1,2,3}, {2,3}, {4,5,6}};

nums[0][1] ?

nums[0] = {1,2,3}

注意:

二维数组,创建数组是,[][] 第一个必须指明长度

声明的有效方式:

int[][ ] ia1 = new int[2][3];

int[][ ] ia2 = new int[2][];

ia2[0] = new int[2], ia2[1] = new int[3];

Teacher[][] ta;

ta = new Teacher[2][];

ta[0] = new Teacher[3];

ta[1] = new Teacher[4];

无效的声明方式

int[][ ] ia1 = new int[][3];

Teacher[][] ta = new Teacher[][5];

六、面向对象-类和对象

6.1  类与对象的概念

6.1.1  面向对象的概念

面向对象编程:OOP(Object-Oriented Programming)。

一切皆对象!比如学生对象、空调对象等等。

面向对象的三大特征是:封装、继承、多态,(抽象)。

到目前为止我们已经遇到了String、Scanner、Math、Arrays等类,这些类都是Java类库中提供的类。除了可以使用类库提供的类之外,我们也可以定义自己的类,并使用自定义的类。

6.1.2  使用类和对象开发程序的基本步骤

对于面向对象编程,主要工作就是编写类。面向对象开发的步骤:

  1. 开发类,类 = 属性(成员变量) + 方法(成员方法)
  2. 通过new关键字和类创建对象
  3. 使用类中的属性和方法:对象.属性名  对象.方法名()

6.1.3  类与对象

从概念上讲,类表示一类事物,从语法上讲,类是一种数据类型

(1)类是一种逻辑结构,对具有公共特征和行为(功能)的一个群体进行描述。例如可以定义Student类描述学生的公共属性和行为,定义一个Teacher类,描述老师的公共属性和行为。

(2)定义了类之后,就可以根据类创建(new)出一个对象(实例)。比如学生张三,王老师。

通俗地说:

类定义了一种新的数据类型(复合类型)。对象就是根据类定义的变量。可以将类看做是复合类型。

类是对象的模板(template),对象是类的实例(instance)。因为对象是类的实例,所以经常会看到交换使用“对象”和“实例”这两个词。

6.2  定义类

类   = 属性  +  方法

6.2.1  类的一般形式

class 类名 {  //类名通常以大写字母开始

类型  变量1;

类型  变量2;

…

类型 方法名(参数列表) {

// 方法体

}

…

}

在类中定义的变量和方法都称为类的成员。所以变量又称为成员变量,方法又称为成员方法。

6.2.2  类的属性

类的成员变量又称为类的属性。

public class Student {

/**

 * 属性 成员变量

 * 类的{}内直接声明(定义)的变量  叫  成员变量/实例变量

 */

String  name;

int  age;

double  score;

}

属性属于类的某个具体对象。类的每个实例(即,类的每个对象)都包含这些变量的副本,因此在类中定义的变量又被称为实例变量

6.2.2  类的方法

方法是对象行为特征的抽象,类具有的共性的功能操作,称之为方法。方法是个“黑匣子”,完成某个特定的应用程序功能。

方法的基本语法:

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

//功能代码

}

形参可以为空,可以有多个,形参的类型可以是基本类型也可以是引用类型。p

ublic class Student {

String  name;

int  age;

double  score;



void  study(){

//

}



void  show(){

//

}

}

注意:

方法中定义变量称为局部变量。

如果没有返回值,则方法的返回类型必须为void

当方法有具体的返回类型时,则必须使用return语句返回一种值。

6.3  对象的创建于使用

6.3.1  对象的声明与创建

基本类型和引用类型的区别:

基本类型:int  a = 10;

Student   stu1;         //声明对象的引用

stu1  =  new Student();  //创建对象

变量a保存的是实际数据;变量stu1保存的是实际数据在内存的中的位置。

说明:

引用相当于标签,对象相当于具体的物体

6.3.2  访问对象的成员

public static void main(String[] args) {



Student stu1 = new Student();

stu1.name = "张三";    //访问对象的属性

stu1.age = 20;

stu1.score=95.5;

stu1.show();           //方法调用



Student stu2 = new Student();

stu2.name = "李四";    //访问对象的属性

stu2.age = 22;

stu2.score=98;

stu2.show();           //方法调用



Student stu3 = stu2;

sut2.show();

}

注意:

属性属于类的具体对象,不同对象的属性值通常是不同的。

虽然方法也是通过对象调用的,但是各对象共享相同的方法。

6.3.3  为引用变量赋值

Box b1 = new Box(); //创建对象,让b1指向(引用)所创建的对象

Box b2 = b1;

注意:

b1和b2引用同一个对象。  对象b1:本质是指b1指向的对象

b2.length = 5;  //将b2指向的Box对象的长度设置为5,

System.out.println(b1.length)  //输出??

对象引用与对象的关系:

(1)对象引用,有时也称为对象引用变量,或称为引用变量。

(2)对象引用与对象在物理上是两个不同的东西。

(3)对于上图,我们通常说b1引用(有时也称为指向)图中的那个Box对象。

(4)对象只能通过对象引用来操作。有时直接使用对象引用代指对象,例如对于上面的例子,有时会直接将b1引用的对象称为“对象b1”或“”b1对象。

(5)将一个对象引用赋值给另一个对象引用,则两个引用变量指向同一个对象。

6.3.4  对象比较

对引用变量进行相等性比较,例如b1==b2,是比较两个引用变量是否引用同一个对象,所以b1==b2的结果为true。对对象引用进行相等性比较,有时也直接称为对象的相等性比较。

6.4  构造器/构造方法

6.4.1  构造方法的语法

构造方法也叫做构造器

构造方法的作用:开辟内存空间、创建实例、初始化属性值。

构造方法的特点:

(1)方法名与类名相同  (大写敏感)public  Student( );

(2)不能声明返回类型,void也不行   //没有返回类型(也算对,但是不严谨)

(3)不能使用return语句返回内容/不能有返回值

(4)通常为public

注意:

(1)如果没有明确提供构造方法,则系统会提供一个默认的构造方法,默认构造方法(也称为缺省构造方法)没有参数。

(2)如果我们提供了一个构造方法,则系统不再提供无参数的默认构造方法。

(3)如果我们提供了一个有参数的构造方法,同时又需要无参构造方法的话,则必须同时提供一个无参数的构造方法。

6.4.2  new运算符

new运算符实际是就是调用构造方法,创建一个新对象。当进入到构造方法内部时,实际上对象已经创建完毕,可以在构造方法中为各成员变量赋值。

6.4.3  this关键字

在类的内部,可以在任何方法中使用this引用当前对象。

使用this关键字解决在实例变量和局部变量之间可能发生的任何名称冲突。

局部变量,包括方法的形参,可以和类的实例变量重名。当局部变量和实例变量具有相同的名称时,局部变量隐藏了实例变量。

6.5  方法深入分析

方法可以看做是独立的功能模块,供其他模块调用,功能模块要有输入、输出,对于方法而言输入就是方法的参数,输出就是方法的返回值。调用者通过参数将需要输入的数据传递给方法,方法通过返回值将输出返回给调用者。

6.5.1  方法定义

1、方法的六个要素:访问修饰符、返回类型、方法名、形参、方法体、返回值

2、方法必须有返回类型(构造方法除外),可以省略访问修饰符  默认default

3、可以有参数,也可以没有参数

6.5.2  方法调用

在一个方法中调用另外一个方法

方法调用有两种情况:

调用相同类中的方法:可以直接调用。(本质上是使用this关键字调用)

调用其他类中的方法:对象.方法名

1、同一个类中的方法相互调用:可以直接调用(本质上是使用this关键字调用)

2、不同类中的方法相互调用:通过对象调用

案例演示:

通过Box类中的calVolume()方法演示方法调用。

6.5.3  参数传递与返回值

1、实参与形参的概念

2、方法调用的执行过程

案例演示:Calculator类

6.5.4  return关键字

(1)return语句用于明确地从一个方法返回。即,return语句导致程序的执行控制转移回到方法的调用者。

(2)如果return之后还有代码,也不会执行。

public static int test1(int a){

  if(a>10){

    return 1;

  }

if(a>20){

    return 2;

  }

  else{

     return 3;

  }

}

(3)如果方法的返回类型为void,可以使用return跳出方法,但是不能使用return返回数据。

public  static  void  test2(int b){

if(b > 10){

System.out.println(1);

return;

}

if(b > 20){

System.out.println(2);

return;

}

else{

System.out.println(3);

return;

}

}

(4)方法的返回值可以是对象。

6.5.5  参数传递的两种方式

方法调用中发生的数据传送是单向的。即只能把实参的值传送给形参,而不能把形参的值反向地传送给实参。因此在函数调用过程中,形参的值发生改变,而实参中的值不会变化。

两种参数传递方式:

值传递:参数类型为基本类型,参数传递时是将实参的值赋给形参,实参和形参是不同的变量。

引用传递:引用类型(对象)作为参数,参数传递时,实参和形参指向同一个对象。所以在方法中修改形参指向的对象会影响到实参所指向的对象(本来就是同一对象)。

6.6  方法重载

6.6.1  方法重载基础

直接切入主题:

在同一个类中名称相同、形参列表不同的多个方法称为重载方法。

特点:

1、方法名相同

2、形参列表不同:形参的类型、形参的个数,形参的顺序

说明:

方法名+形参列表,共同构成了方法的唯一标识。(方法原型/方法签名)

注意的地方:

1、返回值在区分重载方法时不起作用。访问修饰符也不起作用

2、当调用重载方法时,Java使用实参的类型和/或数量确定实际调用哪个版本。

方法重载案例:

完善Calculator类,添加add()方法,计算两个数的和。

两个参数的类型分别为:int、float、double

6.6.2  重载构造方法

示例1:

Box(double length, double width, double height)

Box(double dim)

Box(Box box)

Box()

特别说明:

在某个构造方法中可以使用this()调用重载的构造方法:

public  Box(double dim){

this(dim, dim, dim)

}

示例2:

重载Student类的构造器

Student(String name, int age, double score)

Student(String name, int age)

6.7  static关键字

类:成员变量+成员方法

对于类中的成员变量和成员方法都可以使用static进行修饰。

main()方法是最常见的静态成员的例子。main()方法被声明为静态的,因为需要在创建所有对象之前调用该方法。

6.7.1  静态变量

对于类中的成员变量可以使用static进行修饰,这种变量叫做静态变量。

没有使用static修饰的变量叫做实例变量。

实例变量与静态变量的区别:

(1)是否共享

实例变量:不共享,类的每个对象(实例)都有自己的实例变量

静态变量:共享,类的所有对象都共享同一个变量

(2)访问方式

实例变量:只能通过对象访问

静态变量:类名.变量名(推荐)、对象.变量名(不推荐)

(3)初始化时机

实例变量:创建类的对象时初始化

静态变量:当类被虚拟机加载初始化,创建类的任意对象之前已经初始化。

案例:(演示静态变量的访问方式、不同实例共享相同的值)

6.7.2  静态方法

对于类中的方法也可以使用static进行修饰,这种方法称为静态方法。

没有使用static修饰的方法称为实例方法。

静态方法和实例方法的区别(访问方式):

静态方法:可以通过类名(推荐)和对象(不推荐)

实例方法:只能通过对象访问

静态方法的特点:

不需要创建类的对象就可以直接通过类名调用静态方法,例如Math.random()。

静态的方法有几个限制:

  1. 只能访问类中的其他静态成员(静态变量、静态方法)
  2. 不能以任何方式引用this或super关键字

6.7.3  关于static的几点说明

1、static的本质作用是区分成员属于类还是属于实例(对象)。

2、通常把使用static修饰的变量和方法称为类变量和类方法,有时也称为静态变量和静态方法,把不使用static修饰的变量和方法称为实例变量和实例方法。

七、面向对象-封装

封装(英语:Encapsulation)是面向对象的三大特征之一

类 = 属性 + 方法,类是对属性和方法的封装。类封装了类的成员。

1)封装:是指隐藏对象的属性和实际细节,仅对外提供公共的访问方式

2)封装的优点:

  • 1. 良好的封装能够减少耦合。

  • 2. 类内部的结构可以自由修改。

  • 3. 可以对成员变量进行更精确的控制。

  • 4. 隐藏信息,实现细节。

3)封装的原则:

  1. 隐藏内部实现细节‌:通过将类的属性和方法设置为私有,仅通过公共接口进行访问和操作,从而隐藏类的内部实现细节。
  2. 提供公共接口‌:提供公共的方法来操作类的属性,确保外部只能通过这些公共方法访问和修改类的内部状态。
  3. 单一职责原则‌:每个类应该只负责一项明确的功能,避免一个类承担过多的责任。
  4. 安全性‌:通过封装可以保证数据的安全性和一致性,防止未经授权的访问和修改。
  5. 简化使用‌:对外提供简捷的接口,使用者不必了解具体的实现细节,只需通过特定的访问权限使用类的成员。

7.1 Java封装的步骤

通常的做法:

(1)将类的属性的访问权限设置为private,提供访问权限为public的set和get方法。在有些情况下不提供set和get方法,有时只提供其中的一个

(2)提供合理的构造方法,即开发相应参数的构造方法,方便实例化对象。

(3)类的全部或部分方法的访问权限为public,类的公有方法是类对外开放的接口,供外部代码使用类的功能。类的私有方法通常是辅助方法实现部分功能,供类的公有方法调用。

让我们来看一个java封装类的例子:

public class EncapTest{
 
   private String name;
   private String idNum;
   private int age;
 
   public int getAge(){
      return age;
   }
 
   public String getName(){
      return name;
   }
 
   public String getIdNum(){
      return idNum;
   }
 
   public void setAge( int newAge){
      age = newAge;
   }
 
   public void setName(String newName){
      name = newName;
   }
 
   public void setIdNum( String newId){
      idNum = newId;
   }
}

以上实例中public方法是外部类访问该类成员变量的入口。

通常情况下,这些方法被称为getter和setter方法。

因此,任何要访问类中私有成员变量的类都要通过这些getter和setter方法。

通过如下的例子说明EncapTest类的变量怎样被访问:

public class RunEncap{
   public static void main(String args[]){
      EncapTest encap = new EncapTest();
      encap.setName("James");
      encap.setAge(20);
      encap.setIdNum("12343ms");
 
      System.out.print("Name : " + encap.getName()+ 
                             " Age : "+ encap.getAge());
    }
}

7.2 

(1)包的概念

类通常位于某个包中,包(packages)是多个类的容器。它们用于保持类的名称空间相互隔离,类的全名是“包名.类名”。因此包是一种命名机制。

例如:

Java类库中的类,分别包含在不同的包中:java.lang;java.util。

例如:

String类位于java.lang包中   java.lang.String  java.util.Scanner

(2)定义包

package  pack1;

包名的命名规范:

1、不能包含特殊符号;2、不能以数字开头;3、通常是小写字母开头

类的全名为:包名.类名。

(3)层次化的包

例如:

package  org.xiaoxie.com

package  org.xiaoxie

包org.xiaoxie与org.xiaoxie.com是两个不同的包,没有关系。

(4)包与目录结构

位于包中的类,在文件系统中也必须有与包名层次相同的目录结构。

需要指出的是,包名与文件目录结构一致是针对.class文件而言的,对于源代码文件没有这一要求,但是通常也将源代码文件放到与包名一致的目录结构中。并且建议将源文件与类文件分开存放。

class文件的存储位置与包名必须一致:因为执行class文件时,只指定类的全名,然后根据类的全名去查找class文件。

(5)导包

类的全名为:包名.类名。例如在org.xiaoxie包中定义的Student类,其全名为org.xiaoxie.Student。

当在不同的包中使用某个类时,需要使用类的全名,如果包名很长的话,使用类的全名不是很方便,这时可以通过导入包来避免使用类的全名。

导入包的目的:减少输入

导入包的两种方式

import  java.util.Scanner;

import  java.util.*;

包既是一种命名机制,也是一种可见性控制机制。可以在包中定义该包外部的代码不能访问的类成员。

7.3  访问范围

在定义类时,可以通过访问修饰符控制类中成员的访问范围。

四种访问范围:

本类、本包、本包+不同包中的子类、所有包(全局)

说明:

1、类的全名是:包名.类名,因此包p1中类A的全名是p1.A,包p2中类A的全面是p2.A。

2、假定类SubB是类B的子类

7.4  访问修饰符与访问控制

在定义类时,可以通过访问修饰符控制类中成员的访问范围。

可以通过不同的访问修饰符控制类成员的可见范围,即控制类的成员在多大的范围是可见的。

private

默认(default)

protected

public

本类

本包

本包+子类(不同包)

全局(所有包)

访问范围:  本类   <  本包   <  本包+不同包的子类  <   全局(所有包)

访问修饰符:private  <  缺省(default) < protected  <  public

两种用法:

1、指定类成员的访问范围

2、指定整个类的访问范围(本包、全局)

八、向对象-继承

8.1  继承基础

继承是面向对象的基本特征之一。

8.1.1  继承的概念

使用继承可以为一系列相关对象定义共同特征的一般类,然后其他类(更特殊的类)可以继承这个一般类,每个进行继承的类都可以添加其特有的内容。

被继承的类称为超类(super class)/父类,继承的类称为派生类/子类(subclass)。

一旦创建了一个父类,就可以使用该超类创建任意数量的更特殊的子类。

继承类型:

需要注意的是 Java 不支持多继承,但支持多重继承。

8.1.2  继承的语法

继承使用关键字extends(扩展)实现。

public class A extends SuperA{

//扩展

}

优点:

子类可以从父类继承属性和部分方法,自己再增加新的属性和方法。通过继承子类可以重用父类的方法和属性,减少代码重复编写,便于维护、代码扩展。

示例:

// 父类
class ParentClass {
    int parentVariable;
 
    void parentMethod() {
        System.out.println("This is a parent method.");
    }
}
 
// 子类
class ChildClass extends ParentClass {
    int childVariable;
 
    void childMethod() {
        System.out.println("This is a child method.");
    }
}
 
// 测试类
public class Main {
    public static void main(String[] args) {
        ChildClass child = new ChildClass();
        child.parentMethod();  // 继承自父类
        child.childMethod();   // 子类自己的方法
    }
}

以上代码运行输出结果为:

This is a parent method.
This is a child method.

 ChildClass通过extends关键字继承了ParentClass。因此,ChildClass拥有ParentClass中的parentMethod()方法和parentVariable变量。同时,ChildClass还可以有它自己的方法和变量,例如childMethod()和childVariable。

8.1.3  成员继承的规则

(1)子类不能从父类继承构造方法。

(2)属性的继承:理论上子类会继承父类的全部成员变量(属性),但是子类不能访问父类的私有成员变量,如果子类与父类在不同包中,子类也不能访问父类中具有默认访问权限的成员变量。

(3)方法的继承:根据访问权限,在子类中能够访问的那些方法都可以继承。

  1. 父类中访问权限为public和protected的方法,子类可以继承。
  2. 父类中访问权限为private的方法,不能继承
  3. 父类中访问权限为默认的方法,如果子类和父类同包,可以继承,不同包不能继承。

8.1.4  子类的构造方法

(1)构造方法的调用顺序

在类继承层次中按照继承的顺序从父类到子类调用构造方法

(2)在子类的构造方法中,一定会先调用父类的构造方法。super();

(3)子类的每个构造方法都会隐式的调用父类的无参数构造方法,如果想调用父类的其他构造方法,必须使用super(参数列表)来显式调用。通常需要提供无参数构造方法  如果子类的构造犯法中IE  你很漂亮 但是我不喜欢

说明:编写类时,通常需要提供无参数构造方法。

(4)如果父类没有无参的构造方法,或者想调用父类的有参构造方法,则在子类的构造方法中必须显式使用super(xxx)调用父类有参构造方法。这时super(xxx)必须是子类中的第一条语句。

(5)通常的做法:

在父类中定义有参数的构造方法,负责初始化父类的成员变量。

在子类的构造方法中,先调用父类的构造方法完成从父类继承来的那些成员变量,然后初始化子类中特有的成员变量。

通常为每个类添加无参的构造方法。

注意:

如果父类中定义了一个有参数的构造方法,系统就不会再为父类提供默认的构造方法。这时,在子类的构造方法中,必须使用super(xxx)显示调用父类的有参构造方法。

8.1.5  创建多级继承层次 

//多继承(类不支持多继承)

public  Person( ){

}

public  Student( ) extends Person{

}

public  BawieStudent( )  extends Student{

}

注意:

多级继承和多继承。多继承是指一个类有多个父类,Java不支持多继承。

一个类只能有一个父类

一个父类可以有多个子类

8.1.6  超类引用变量可以引用子类对象

Animal  ani = null;     //声明超类的变量

Dog dog = new Dog();  //创建子类对象

ani = dog;            //将子类对象赋给父类的引用

ani = new Dog();    //创建一个新的子类对象,赋给父类引用变量

可以将子类的对象赋给父类的引用变量,但是这时使用父类的引用变量只能访问父类中定义的那些成员变量。换句话说,可以访问哪些成员是由引用变量的类型决定的,而不是由所引用的对象类型决定的。

8.1.7  对象的转型

Animal a = new Dog();  //小转大  可以自动进行

a.getLayal();  //语法错误,这时通过a只能使用父类中定义的成员变量。编译时就确定

a.eat();  //

Animal a = new Dog();

Dog d = (Dog)a;  //正确   大转小, 需要强制转换



Dog d = new Animal();  //错误

Dog d = (Dog)new Animal();  //语法没错,可以编译,但运行时会抛出异常

Cat c = new Cat();

d = (Dog)c; //不正确

1、子类对象 赋给 父类引用  可以,自动转换

2、父类引用  赋给  子类引用  需要强转,前提:父类引用确实指向了正确的子类对象

8.1.8  方法重写介绍

当子类从父类中继承来的方法不能满足需要时,子类可以重写该方法,重写方法要求方法名与参数列表都相同。

8.1.9  变量隐藏

当在子类中定义的成员变量与父类中的变量具有相同名称时,子类中定义的变量会隐藏父类中定义的变量。

class Father{

double money = 100_000;



public void showMoney(){

System.out.println(money);

}

}

class Son extends Father{

double money = 10_000;



public void showMoney(){

System.out.println(super.money);

System.out.println(money);

}

}

8.2  super关键字

关键字super用于调用/访问从父类中继承来的实例变量和方法。

super有两种用法。第一种用于调用超类的构造方法。第二种用于访问超类中被子类的某个成员隐藏的成员(变量和方法)。

8.2.1  使用super()调用父类的构造方法

  1. 在子类中使用super()调用父类的构造方法,必须是第一条语句
  2. 在本类中可以使用this()调用重载的构造方法,也必须是第一条语句
  3. 在子类的构造方法中this()和super()不能同时使用

8.2.2  使用super访问父类中被子类隐藏的成员

父类的属性被子类继承,如果子类又添加了名称相同的属性,则子类有两个相同名称的属性,如果父类型对象调用属性,就是父类的,如果是子类型对象调用就是子类的属性。

当子类需要引用它的直接超类时,就可以使用关键字super。

this的两个作用:

第一个作用调用重载的构造方法

第二个作用:当局部变量和成员变量的名称重名时,进行区分

8.3  Object

8.3.1  Object类介绍

所有其他类都是Object的子类。也就是说,Object是所有其他类的超类。这意味着Object类型的引用变量可以引用任何其他类的对象。此外,因为数组也是作为类实现的,所以Object类型的变量也可以引用任何数组。

Object类定义了下面列出的方法,这意味着所有对象都可以使用这些方法。

方  法

用  途

Object clone()

创建一个和将要复制的对象完全相同的新对象。

boolean equals(Object object)

确定一个对象是否和另外一个对象相等

void finalize()

在回收不再使用的对象前调用

Class<?> getClass()

在运行时获取对象的类

int hashCode()

返回与调用对象相关联的散列值(哈希码)

void notify()

恢复执行在调用对象上等待的某个线程

void notifyAll()

恢复执行在调用对象上等待的所有线程

String toString()

返回一个描述对象的字符串

void wait()

void wait(long milliseconds)

void wait (ling milliseconds,

int nanoseconds)

等待另一个线程的执行

8.3.2  equals()方法与对象相等性比较

Object类中的equals()方法实现等价于“==”运算符

对于引用类型“==”的含义是:两个引用是否是指向同一个对象

如果希望使用不同的规则,就需要重写equals()方法。

例如:

String类对equals()方法进行了重写,重写后的equals方法比较两个字符串的内容是否相同。

String s1 = new String( “abc”);

String s2 = new String(“abc”);

对于引用类型都比较:

if(s1 == s2) //比较是s1与s2是否指向同一个对象

s1.equals(s2);

因为不同的类可以重写equals方法,所以euqals方法比较的行为可能不同

equals方法最初是Object类中定义,在该类中的默认实现等价于“==”

String类对equals进行了重写,比较两个字符串中内容是否一致

案例:

重写Box类的equals()方法

8.3.3  重写toString()方法

直接打印对象时,默认调用对象的toString()方法

Object类的toString方法输出格式:

getClass().getName() + '@' + Integer.toHexString(hashCode())

自己定义的类可以重写toString()

8.4  final

8.4.1  final修饰变量、方法、类

  1. 如果final修饰变量,变量就是常量,常量不可修改,定义时必须初始化
  2. 如果final修饰方法,方法就不能被子类重写
  3. 如果final修饰类,类就不能再被扩展,不能再有子类。Java类库中的String、Math就是final类。

8.4.2  引用类型的常量

如果常量是基本数据类型,不可以再修改。

如果常量是引用类型,不能再将其他对象赋给该引用,但可以使用该引用改变对象内部的属性。

例如:

final  Student  s = new Student(“zhangsan”,20);

s = new Student(“李四”,20); //错误

s.setName(“李四”);        //正确

标签:Java,详细,构造方法,int,收藏,对象,数组,方法,变量
From: https://blog.csdn.net/qq_41320700/article/details/143376909

相关文章

  • sort() 排序和qsort() 排序(超详细)
    目录前言一、qsort()是什么?1.核心代码:函数的原型参数含义:实际使用(一般只对qsor()函数进行微调)以整形数组进行演示2.其他类型比较一级排序二级排序多级排序二、sort()是什么?1.自动调用(从小到大)2.自定义调用一级排序多级排序三.sort()排序和qsort()排序的区别及各自特......
  • Java多线程--Thread类的那些事3.--线程的6中状态和sleep()和 join()
      一.sleep()方法  首先在Thead类中有一个静态的sleep()方法,可以让线程进入到休眠状态即TEMD-WAITING状  在调用sleep()方法时需要注意的是在哪个线程里面调用sleep()方法,哪个线程就会进入阻塞状态.,在这个线程中的其他线程不会发生阻塞,只有当休眠时间到来这个......
  • 【面试题系列Java】Java基础面试题
    对于Java开发工程师而言,掌握Java基础、数据库、框架、Java虚拟机、Java并发编程等知识是必不可少的。以下是一些常见的Java开发工程师面试题及答案,供大家参考。博主介绍上海交大毕业,大厂资深Java后端工程师《Java全套学习资料》作者专注于系统架构设计和高并发解决方......
  • java字符串中得到某个字符,字符串的遍历,截取,替换
    有点详细,请耐心找您需要的看,谢谢!1得到某个字符2:字符串的遍历3:字符串的截取4:字符串的替换//以上根据实际需要输入字符常量时别忘了带""变量就直接输入;......
  • Java进阶学习笔记64——IO流
    IO流:输入输出流,就是读写数据的。IO流的应用场景:怎么去学习IO流?1、先搞清楚IO流的分类、体系?2、再挨个学习每个IO流的作用、用法。IO流的分类:按流的方向分为:按流中数据的最小单位,分为: IO流总体上来看就有四大流:字节输入流: 把磁盘或网络中的数据以一个个......
  • Java进阶学习笔记63——字符集
    常见字符集介绍:美国人:英文字母(大小写)数字、标点符号、特殊字符。标准字符集:ASCII码:标准ASCII字符集:ASCII:美国信息交换标准代码,包括了英文、符号等。标准ASCII使用1个字节存储一个字符,首位是0,总共表示128个字符,对美国人老说完全够用。中国人自己的字符集:GBK(汉字内......
  • 基于Java+SpringBoot+Mysql实现的快递柜寄取快递系统功能实现二
    一、前言介绍:1.1项目摘要随着电子商务的迅猛发展和城市化进程的加快,快递业务量呈现出爆炸式增长的趋势。传统的快递寄取方式,如人工配送和定点领取,已经无法满足现代社会的快速、便捷需求。这些问题不仅影响了快递服务的效率,也增加了快递员和消费者的不便。在这样的背景下,快递柜......
  • C语言复习总结超详细版(1)小白转身即变 有实例超级详细
    废话不多说直接开整注:本博文超级详细但是还是适合有C语言基础的观看 耗时很久,内容不会有问题但是 ⚠️字体晦涩望见谅引子第一个C语言程序#include<stdio.h>intmain(){printf("Hello,LJY!\n");return0;} main函数每个C语⾔程序不管有多少⾏代码......
  • 基于Java+SpringBoot+Mysql实现的快递柜寄取快递系统功能实现一
    一、前言介绍:1.1项目摘要随着电子商务的迅猛发展和城市化进程的加快,快递业务量呈现出爆炸式增长的趋势。传统的快递寄取方式,如人工配送和定点领取,已经无法满足现代社会的快速、便捷需求。这些问题不仅影响了快递服务的效率,也增加了快递员和消费者的不便。在这样的背景下,快递柜......
  • 基于SpringBoot+Vue+uniapp的宿舍管理系统的详细设计和实现(源码+lw+部署文档+讲解等)
    文章目录前言详细视频演示具体实现截图技术栈后端框架SpringBoot前端框架Vue持久层框架MyBaitsPlus系统测试系统测试目的系统功能测试系统测试结论为什么选择我代码参考数据库参考源码获取前言......