ITMO-Study-Note

主页/Java/代码笔记

目录

Java主类结构

public class Main {
    public static void main(String[] args) {
        System.out.println("Hello world!");
    }
}

基本数据类型

Java中有8种基本数据类型来存储数值、字符和布尔值

数据类型 内存空间(8位等于1字节) 取值范围
byte 8位 -128~127
short 16位 -32768~32767
int 32位 -2147483648~2147483647
long 64位 -9223372036854775808~9223372036854775807

定义int型变量

int x;
int x,y;
int x = 450,y = -462;

变量与常量

在程序执行过程中,其值不能被改变的量称为常量,其值能被改变的量称为变量

运算符

数组

public class Rakel { public static void main(String[] args) { String b[]=new String[]{“ab”,”cd”,”ef”,”yz”}; Arrays.sort(b); //对数组从小到大进行排序(Arrays的方法sort) int x=Arrays.binarySearch(b,0,2,”cd”); System.out.println(“cd的索引位置为:”+x); } }

- ### 数组排序算法
- #### 冒泡排序
  - 冒泡排序的基本思想是**对比相邻的元素值**,如果满足条件就交换元素值,**把较小的元素移动到数组前面,把大的元素移动到数组后面**(也就是交换两个元素的位置),这样较小的元素就像气泡一样从底部上升到顶部。
- 冒泡算法由**双层循环**实现,其中**外层循环用于控制排序轮数**,一般为要排序的
数组长度减1次,因为最后一次循环只剩下一个数组元素,不需要对比,同时数组已
经完成排序了。而**内层循环主要用于对比数组中每个邻近元素的大小**,以确定是否
交换位置,对比和交换次数随排序轮数而减少。
![](/Java/pic/java16.png)
- 实例代码:

public class BubbleSort { public static void main(String[] args) { //创建一个乱序的数组元素 int[] array={34,45,89,12,23,54,75}; //创建冒泡排序类的对象 BubbleSort sorter=new BubbleSort(); //调用排序方法将数组排序 sorter.sort(array); } /** * * @param array//要排序的数组 * */ public void sort(int[]array){ for (int i=1;i<array.length;i++){ //比较相邻两个元素,较大的数往后冒泡 for (int j=0;j<array.length-i;j++){ if (array[j] > array[j+1]){ int temp=array[j];//把第一个元素值保存到临时变量中 array[j]=array[j+1];//把第二个元素值保存到第一个元素单元中 array[j+1]=temp;//把临时变量(也就是第一个元素原值)保存到第二个元素中 } } } showArray(array); //输出冒泡排序后的数组元素 } /** * //显示数组中的所有元素 * @param array * */ public void showArray(int[]array){ for (int i:array){ //遍历数组 System.out.print(“>”+i); //输出每个数组元素值 } System.out.println(); } }

- #### 直接选择排序
  - 直接选择排序方法属于选择排序的一种,它的排序速度要比冒泡排序快一些,也是常用的排序算法
  - 直接选择排序的基本思想是将指定排序位置与其他数组元素分别对比,如果满足条件就交换元素值。注意这里与冒泡排序的区别,不是交换相邻元素,而是**把满足条件的元素与指定的排序位置交换**(如从最后一个元素开始排序),**这样排序好的位置逐渐扩大,最后整个数组都成为已排序好的格式**。
  - 实例代码:

/** * * * */ public class Selectsort { public static void main(String[] args) { int[]array={1,32,45,36,67,89,12}; Selectsort sorter=new Selectsort(); sorter.sort(array); } /** * * @param array * */ public void sort(int[]array){ //调用上面sort方法及其变量 int index; for (int i=1;i<=array.length;i++){ index=0; for (int j=1;j<=array.length-i;j++){ if (array[j]>array[index]){ index=j; } } int temp=array[array.length-i]; array[array.length-i]=array[index]; array[index]=temp; } showArray(array); } /** * * * @param array * */ public void showArray(int[]array){ for (int i:array){ System.out.print(“>”+i);; } System.out.println(); } }

- #### 反转排序
  - 反转排序就是以相反的顺序把原有数组的内容重新排序。
  - 反转排序的基本思想比较简单,也很好理解,其实现思路就是把数组最后一个元素与第一个元素替换,倒数第二个元素与第二个元素替换,依此类推,直到把所有数组元素反转替换。
  - 实例代码:

/** * * * */ public class ReverseSort { public static void main(String[] args) { int[] array={13,20,32,56,78,90}; ReverseSort sorter=new ReverseSort(); sorter.sort(array); } /** * * @param array * 要排序的数组 */ public void sort(int[]array) { System.out.println(“数组原有内容:”); showArray(array); int temp; int len=array.length; for (int i=0;i<len/2;i++){ temp=array[i]; array[i]=array[len-1-i]; array[len-1-i]=temp; } System.out.println(“数组反转后内容:”); showArray(array); } /** * * * @param array * 要显示的数组 */ public void showArray(int[]array){ for (int i:array){ System.out.println(“\t”+i); } System.out.println(); } }

- ### 类和对象
- #### 类
  - 类是**封装对象的属性和行为的载体**,而在Java语言中对象的属性以**成员变量**的形式存在,对象的方法以**成员方法**的形式存在。
- **成员变量**
- 为了了解成员变量,首先定义一个图书类,成员变量对应于类对象的属性,在Book类中设置3个成员变量,分别为id、name和category,分别对应于图书编号、图书名称和图书类别3个图书属性。
- 实例代码:

public class book { private String name; //定义成员变量

public String getName(){ //定义成员方法
    int id=0; //定义局部变量
    setName("Java");
    return id+this.name; 
}
private void setName(String name){ //定义一个setName()成员方法
    this.name=name;
}
public book getbook(){
    return this;
} } ``` - **成员方法** - 定义成员方法的语法格式如下: ``` 权限修饰符 返回值类型 方法名(参数类型 参数名){   ...//方法体   return 返回值; }   ``` - 一个成员方法可以有参数,这个参数可以是**对象**,也可以是**基本数据类型的变量**,同时成员方法有返回值和不返回任何值的选择,如果方法需要返回值,可以在方法体中使用`return`关键字,使用这个关键字后,方法的执行将被终止 - **权限修饰符**   - Java中的权限修饰符主要包括`private`、`public`和`protected`,这些修饰符控制着对类和类的成员变量以及成员方法的访问。如果一个类的成员变量或成员方法被修饰为`private`,则该成员变量**只能在本类中被使用**,在**子类中是不可见的**,并且对其他包的类也是不可见的。如果将类的成员变量和成员方法的访问权限设置为`public`,那么除了可以在**本类使用这些数据之外,还可以在子类和其他包的类中使用**。如果一个类的访问权限被设置为`private`,**这个类将隐藏其内的所有数据,以免用户直接访问它**。如果需要使类中的数据被子类或其他包中的类使用,可以将这个类设置为`public`访问权限。如果一个类使用`protected`修饰符,那么只有本包内的该类的子类或其他类可以访问此类中的成员变量和成员方法。 - **局部变量**   - 如果在成员方法内定义一个变量,那么这个变量被称为局部变量。 - **局部变量的有效范围**   - 可以将局部变量的有效范围称为**变量的作用域**,局部变量的有效范围从该变量的声明开始到该变量的结束为止。 ![](/Java/pic/java17.png) - **`this`关键字**   - 使用this关键字来代表本类对象的引用,this关键字被隐式地用于引用对象的成员变量和方法   - 事实上,this引用的就是本类的一个对象。在局部变量或方法参数覆盖了成员变量时,如上面代码的情况,就要添加this关键字明确引用的是类成员还是局部变量或方法参数。 - **类的构造方法**   - 在类中除了成员方法之外,还存在一种特殊类型的方法,那就是构造方法。构造方法是一个与类同名的方法,对象的创建就是通过构造方法完成的。每当类实例化一个对象时,类都会自动调用构造方法。   - 构造方法**没有返回值**。   - 构造方法的名称要与**本类的名称相同**。 - #### 静态变量、常量和方法   - 由`static`修饰的变量、常量和方法被称作静态变量、常量和方法。   - 被声明为`static`的变量、常量和方法被称为静态成员。静态成员属于类所有,区别于个别对象,可以在本类或其他类使用类名和“.”运算符调用静态成员。 - 对于静态方法(使用规则):   - 在静态方法中不可以使用`this`关键字。   - 在静态方法中不可以直接**调用非静态方法**。  - 调用静态常量,变量以及方法的实例代码: ``` public class StaticTest {
static double PI=3.1456; //定义静态常量
static int id; //定义静态变量

public static void Method1(){ //在类中定义静态方法

}
public void Method2(){ //在类中定义一个非静态方法
    System.out.println(StaticTest.PI); //调用静态常量
    System.out.println(StaticTest.id); //调用静态变量
    StaticTest.Method1(); //调用静态方法
} } ```   - #### 类的主方法 - 在主方法的定义中可以看到其具有以下特性:   - **主方法是静态的**,所以如要直接在主方法中**调用其他方法,则该方法必须也是静态的**。   - 主方法**没有返回值**。   - 主方法的形参为数组。其中args[0]~args[n]分别代表程序的第一个参数到第n个参数,可以使用`args.length`获取**参数的个数**。 - #### 对象 - **对象的创建**   - 准确地说,可以在Java语言中使用`new`操作符**调用构造方法创建对象**。 ![](/Java/pic/java18.png) - **访问对象的属性和行为** - 如果希望成员变量不被其中任何一个对象改变,可以使用`static`关键字。 - 实例代码: ``` public class AccessProperty {
static int i=47; //定义静态成员变量
public void call(){ //定义成员方法
    System.out.println("调用call()方法");
    for(i=0;i<3;i++){
        System.out.print(i+"");
        if (i==2){
            System.out.println("\n");
        }
    }
}
public AccessProperty(){ //定义构造方法
}
public static void main(String[] args) { //定义主方法
    AccessProperty t1=new AccessProperty(); //创建一个对象
    AccessProperty t2=new AccessProperty(); //创建另一个对象
    t2.i=60;
    //使用第一个对象调用类成员变量
    System.out.println("第一个实例对象调用i变量的结果为:"+t1.i++);
    t1.call();//使用第一个对象调用类成员方法
    //使用第二个对象调用类成员变量
    System.out.println("第二个实例对象调用i变量的结果为:"+t2.i);
    t2.call();//使用第二个对象调用类成员方法
} } ``` ![](/Java/pic/java19.png) 从上述运行结果中可以看到,**由于使用t2.i=60语句改变了静态成员变量的值,使用对象t1调用成员变量的值也为60**,这正是**i值被定义为静态成员变量的效果**,即使使用两个对象对同一个静态成员变量进行操作,依然可以改变静态成员变量的值,因为在内存中两个对象同时指向同一块内存区域。`t1.i++`语句执行完毕后,i值变为3。当再次调用`call()`方法时又被重新赋值为0,做循环打印操作。 - #### 对象的引用   - 类名 对象引用名称   - 引用与对象相关联的语法如下:   - `Book book=new Book();` - #### 对象的比较   - 在Java语言中有两种比较对象的方式,分别为`“==”`运算符与`equals()`方法。 - 实例代码: ``` public class Compare {
public static void main(String[] args) {
    String c1=new String("abc"); //创建两个String型对象引用
    String c2=new String("abc");
    String c3=c1; //将c1对象引用赋予c3
    System.out.println("c2==c3的运算结果为:"+(c2==c3));
    System.out.println("c2.equals(c3)的运算结果为:"+(c2.equals(c3)));
} } ``` - 第一个:false 第二个:true - 从上述运行结果中可以看出,`“==”`运算符和`equals()`方法比较的内容是不相同的,`equals()`方法是`String`类中的方法,它**用于比较两个对象引用所指的内容是否相等**;而`“==”`运算符比较的是**两个对象引用的地址是否相等**。由于c1与c2是两个不同的对象引用,两者在内存中的位置不同,而`“String c3=c1;”`语句将c1的 引用赋给c3,所以c1与c3这两个对象引用是相等的,也就是打印c1==c3这样的语句将返回true值。 - ### 包装类 - #### Integer   - `java.lang`包中的`Integer`类、`Long`类和`Short`类,可将基本类型`int、long`和`short`封装成一个类。   - 该类提供了多个方法,能在int类型和`String`类型之间互相转换,同时还提供了其他一些处理int类型时非常有用的常量和方法。 - *构造方法*   - `Integer (int number)`
- 该方法以一个`int`型变量为参数来获取`Integer`对象
- 例:`Integer number = new Integer(7);`   - `Integer (String str)`
- 该方法以一个`String`型变量为参数来获取`Integer`对象。
- 例:`Integer number = new Integer("45");` ![](/Java/pic/java20.png) - `Integer`类中的`parseInt()`方法返回与调用该方法的数值字符串相应的整型 `(int)`值。 - `Integer`类中的`parseInt()`方法返回与调用该方法的数值字符串相应的整型`(int)`值。 - 实例代码: ``` public class Summation {
public static void main(String[] args) {
    String str[]={"23","43","56","67","78"};
    int sum=0;
    for (int i=0;i<str.length;i++){
        int myint=Integer.parseInt(str[i]); //将数组中每个元素转换为int型
        sum=sum+myint; //叠加
    }
    System.out.println("数组的元素之和为:"+sum);
} } ``` |方法|字符串类别| |:----:|:----:| |toString()|十进制字符串| |toBinaryString()|二进制字符串| |toHexString()|十六进制字符串| |toOctalString()|八进制字符串| - 实例代码: ``` ublic class Charac {
public static void main(String[] args) {
    String str=Integer.toString(123);
    String str2=Integer.toBinaryString(123);
    String str3=Integer.toHexString(123);
    String str4=Integer.toOctalString(123);
    System.out.println("'123’的十进制表示为:"+str);
    System.out.println("'123'的二进制表示为:"+str2);
    System.out.println("'123'的十六进制表示为:"+str3);
    System.out.println("'123'的八进制表示为:"+str4);
} } ``` - **常量**   - `MAX_VALUE`:表示int类型可取的最大值,即${2}^{31}$-1。   - `MIN_VALUE`:表示int类型可取的最小值,即${-2}^{31}$。   - `SIZE`:用来以二进制补码形式表示int值的位数。   - `TYPE`:表示基本类型int的Class实例。  - #### Boolean   - 一个`Boolean`类型的对象只包含一个类型为`boolean`的字段。此外,此类还为`boolean`和`String`的相互转换提供了许多方法,并提供了处理`boolean`时非常有用的其他一些常量和方法。 - *构造方法*   - `Boolean(boolean value)`
- 该方法创建一个表示`value`参数的`Boolean`对象。
- 例:`Boolean b = new Boolean(true);`   - `Boolean(String str)`
- 该方法以`String`变量作为参数创建`Boolean`对象。如果`String`参数不为`null`且在忽略大小写时等于true,则分配一个表示`true`值的Boolean对象,否则获得一个`false`值的Boolean对象。
- 以String为变量,例:`Boolean bool = new Boolean("ok");` ![](/Java/pic/java21.png) - #### Byte   - 一个Byte类型的对象只包含一个类型为byte的字段。   - 该类还为`byte`和`String`的相互转换提供了方法,并提供了其他一些处理byte时非常有用的常量和方法。 - *构造方法*   - `Byte(byte value)` 
- 通过这种方法创建的`Byte`对象,可表示指定的`byte`值。
- 例:`byte mybyte = 45; Byte b = new Byte(mybyte);`   - `Byte(String str)` 
- 通过这种方法创建的`Byte`对象,可表示`String`参数所指示的`byte`值。
- `Byte mybyte = new Byte("12");` ![](/Java/pic/java22.png) - 常量同Integer型相同 - #### Character   - `Character`类在对象中包装一个基本类型为`char`的值。一个Character类型的对象包含类型为char的单个字段。 - *构造方法*   - `Character(char value)`   - 该类的构造函数必须是一个`char`类型的数据。通过该构造函数创建的`Character`类对象包含由char类型参数提供的值。一旦Character类被创建,它包含的数值就不能改变了。   - 例:`Character mychar = new Character('s');` ![](/Java/pic/java23.png) - *常量*   - `CONNECTOR_PUNCTUATION`:返回byte型值,表示`Unicode`规范中的常规类别`“Pc”`。   - `TITLECASE_LETTER`:返回`byte`型值,表示`Unicode`规范中的常规类别`“Lt”`。   - `UNASSIGNED`:返回`byte`型值,表示`Unicode`规范中的常规类别`“Cn”`。

public class BigDecimalDemo { static final int location=10; /** * 定义加法方法,参数为加数与被加数 * * @param value1 * 相加的第一个数 * @param value2 * 相加的第二个数 * @return 两数之和 */ public BigDecimal add(double value1,double value2){ BigDecimal b1=new BigDecimal(Double.toString(value1)); BigDecimal b2=new BigDecimal(Double.toString(value2)); return b1.add(b2);//调用加法方法 } /** * 定义减法方法,参数为减数与被减数 * @param value1 被减数 * * @param value2 减数 * * @return 两数之差 */ public BigDecimal sub(double value1,double value2){ BigDecimal b1=new BigDecimal(Double.toString(value1)); BigDecimal b2=new BigDecimal(Double.toString(value2)); return b1.subtract(b2);//调用减法方法 } /** * 定义乘法方法,参数为乘数与被乘数 * * @param value1 * 第一个乘数 * @param value2 * 第二个乘数 * @return */ public BigDecimal mul(double value1,double value2){ BigDecimal b1=new BigDecimal(Double.toString(value1)); BigDecimal b2=new BigDecimal(Double.toString(value2)); return b1.multiply(b2); // 调用乘法方法 } /** * 定义除法方法,参数为除数与被除数 * * @param value1 被除数 * * @param value2 除数 * * @return * */ public BigDecimal div(double value1,double value2){ return div(value1,value2,location);//调用自定义除法方法 } //定义除法方法,将参数分别位除数与被除数以及商小数点后的位数 public BigDecimal div(double value1,double value2,int b){ if (b<0){ System.out.println(“b的值必须大于等于0”); } BigDecimal b1=new BigDecimal(Double.toString(value1)); BigDecimal b2=new BigDecimal(Double.toString(value2)); //调用除法方法,商小数点后保留b位,并将结果进行四舍五入操作 return b1.divide(b2,b,BigDecimal.ROUND_HALF_UP);//调用除法方法 } public static void main(String[] args) { BigDecimalDemo b=new BigDecimalDemo(); System.out.println(“两个数字相加的结果为:”+b.add(-8.0,9.4)); System.out.println(“两个数字相减的结果为:”+b.sub(-8.0,9.4)); System.out.println(“两个数字相乘的结果为:”+b.mul(-8.0,9.4)); System.out.println(“两个数字相除结果,结果小数后保留10位:”+b.div(10,2)); System.out.println(“两个数字相除,保留小数后5位:”+b.div(-8.0,9.4,5)); } }

### 类的高级特性
- #### 导入包
  - 使用`import`关键字导入包
    - import关键字的语法如下: 

import com.lzw.*; //指定com.lzw包中的所有类中的程序都能使用 import com.lzw.Math //指定com.lzw包中的Math类在程序中可以使用

- 在使用`import`关键字时,可以指定类的完整描述,如果为了使用包中更多的类,可以在使用`import`关键字指定时在包指定后加上*,这表示可以在程序中使用包中的所有类。
  - 使用import导入静态成员
    - 使用import导入静态成员的语法如下:

import static 静态成员

- 实例代码:

import static java.lang.Math.max; import static java.lang.System.out; public class ImportTest { public static void main(String[] args) { out.println(“5和7比较大小:”+max(5,7)); } }

### 异常处理
- 异常分为两大类:已检查和未检查
  - 对于未检查异常也叫RunTimeException
![](/Java/pic/java34.png)
- #### 捕捉异常
  - Java语言的异常捕获结构由`try`、`catch`和`finally` 3部分组成。其中,`try`语句块存放的是可能发生异常的Java语句;`catch`程序块在`try`语句块之后,用来激发被捕获的异常;`finally`语句块是**异常处理结构的最后执行部分**,**无论`try`语句块中的代码如何退出**,都将执行`finally`语句块。
- **`try-each`语句**
- 实例代码:

public class Take { public static void main(String[] args) { try { //try语句中包含可能出现异常的程序代码 String str = “Ally”; System.out.println(str + “年龄是:”); int age = Integer.parseInt(“20L”); //数据类型转换 System.out.println(age); } catch (Exception e) { //catch语句用来获取异常信息 e.printStackTrace(); //输出异常性质 } System.out.println(“Program over”); } }

- 注意:
  - `Exception`是`try`代码块传递给catch代码块的变量类型,`e`是变量名。`catch`代码块中语句`“e.getMessage();”`用于输出错误性质。通常,异常处理常用以下3个函数来获取异常的有关信息。
    - `getMessage()`函数:输出错误性质.
    - `toString()`函数:给出异常的类型与性质。
    - `printStackTrace()`函数:指出异常的类型、性质、栈层次及出现在程序中的位置。
- **`finally`语句块**
  - 完整的异常处理语句一定要包含`finally`语句,无论程序中有无异常发生,并且无论之间的`try-catch`是否顺利执行完毕,都会执行`finally`语句。
- #### 常见异常
![](/Java/pic/java29.png)
- #### 自定义异常
  - 在程序中使用自定义异常类,大体可分为以下几个步骤:
    - 创建自定义异常类。
    - 在方法中通过`throw`关键字抛出异常对象。 
    - 如果在当前抛出异常的方法中处理异常,可以使用`try-catch`语句块捕获并处理,否则在方法的声明处通过`throws`关键字指明要抛出给方法调用者的异常,继续进行下一步操作。
    - 在出现异常方法的调用者中捕获并处理异常。
- 实例代码:

public class MyException extends Exception{ public MyException(String ErrorMessage){ super(ErrorMessage); } } public class Tran { static int avg(int number1,int number2)throws MyException{ if (number1<0||number2<0){ throw new MyException(“不可以小于0”); } if (number1>100||number2>100){ throw new MyException(“数值过于大了”); } return (number1+number2)/2; }

public static void main(String[] args) {
    try{
        int result=avg(-1,103);
        System.out.println(result);
    }catch (MyException e){
        System.out.println(e);
    }
} } ``` - 字符串`ErrorMessage`是要输出的错误信息。若想抛出用户自定义的异常对象,要使用`throw`关键字 - #### 在方法中抛出异常   - 若某个方法可能会发生异常,但不想在当前方法中处理这个异常,则可以使用`throws`、`throw`关键字在方法中抛出异常。 - **使用`throws`关键字抛出异常** - 实例代码: ``` public class Shoot {
static void pop() throws NegativeArraySizeException{ //定义方法并抛出NegativeArraySizeException异常
    int arr[]=new int[-3]; //创建数组
}

public static void main(String[] args) {
    try { //try语句处理异常信息
        pop(); //调用pop()方法
    }catch (NegativeArraySizeException e){
        System.out.println("pop()方法抛出的异常");
    }
} } ``` - **使用`throw`关键字抛出异常**   - `throw`关键字通常用于方法体中,并且抛出一个异常对象。程序在执行到`throw`语句时立即终止,它后面的语句都不执行。通过`throw`抛出异常后,如果想在上一级代码中来捕获并处理异常,则需要在抛出异常的方法中使用`throws`关键字在方法的声明中指明要抛出的异常;如果要捕捉`throw`抛出的异常,则必须使用`try-catch`语句块。 - 实例代码: ``` public class MyException2 extends Exception{ //创建自定义异常类
String message; //定义String类型变量
public MyException2(String ErrorMessage){ //父类方法
    message = ErrorMessage;
}
public String GetMessage(){ //覆盖父类方法
    return message;
} } public class Captor {
static int quotient(int x,int y)throws MyException2{ //定义方法中抛出异常
    if (y<0){ //判断参数是否小于0
        throw new MyException2("除数不能是负数"); //异常信息
    }
    return x/y; //返回值
}

public static void main(String[] args) {
    try {
        int result=quotient(4,-3);
    }catch (MyException2 e){
        System.out.println(e.GetMessage());
    }catch (ArithmeticException e){
        System.out.println("除数不能为0");
    }catch (Exception e){
        System.out.println("程序发生了其他的异常");
    }
} } ``` - #### 三种类型的异常处理   - 声明异常   - 抛出异常   - 捕获异常 - #### 运行时异常   - `RuntimeException`异常是程序运行过程中产生的异常。Java类库的每个包中都定义了异常类,所有这些类都是`Throwable`类的子类。`Throwable`类派生了两个子类,分别是`Exception`和`Error`类。`Error`类及其子类用来描述Java运行系统中的内部错误以及资源耗尽的错误,这类错误比较严重。`Exception`类称为**非致命性类**,可以通过捕捉处理使程序继续执行。`Exception`类又根据错误发生的原因分为`RuntimeException`异常和除`RuntimeException`之外的异常

public class Girl implements Happy,Pretty,Extroverted{ @Override public void Happy(){ System.out.println(“开心的女孩”); }

@Override
public void Pretty() {
    System.out.println("漂亮的女孩");
}

@Override
public void Extroverted() {
    System.out.println("外向的女孩");
} } ``` - 女孩类引用三个定义的接口并使用它们包含的方法,从而实现多重继承 - #### 实现多态   - 多态可以通过继承(`extends`)的关系实现,也可以通过接口的形式实现。   - 其实将父类对象应用于子类的特征就是多态。(将子类的对象看作为父类的实例化对象,即可调用父类的方法进而实现子类所需要)   - `Override`(方法覆盖)与`Overload`(方法重载)之间的区别:重载`Overload`表示同一个类中可以有多个名称相同的方法,但这些方法的参数列表各不相同(即参数个数或类型不同),而`Override`不仅名称相同,参数列表也相同。   - 实例代码: ``` public interface Shape { //Shape接口表示一个形状
String name(); } public class Circle implements Shape { //Circle 类实现了 Shape 接口,并重写了 name() 方法。
@Override
public String name() {
    return "圆";
} } public class Square implements Shape { //Square 类也实现了 Shape 接口,并重写了 name() 方法。
@Override
public String name() {
    return "正方形";
} } List<Shape> shapes = new ArrayList<>(); //测试类 Shape circleShape = new Circle(); Shape squareShape = new Square();

shapes.add(circleShape); shapes.add(squareShape);

for (Shape shape : shapes) { System.out.println(shape.name()); }

public class test2 { interface Coach { void Command(); }

interface CoachFactory {
    Coach CreateCoach();
}

static class ACoach implements Coach {
    public void Command() {
        System.out.println("我是A级证书教练,其他都给我衮");
    }
}

static class ACoachFactory implements CoachFactory {
    public Coach CreateCoach() {
        return new ACoach();
    }
}

static class CCoach implements Coach {
    public void Command() {
        System.out.println("我是C级教练");
    }

    static class CCoachFactory implements CoachFactory {
        @Override
        public Coach CreateCoach() {
            return new CCoach();
        }
    }

    public class Demo {
        public static void create(CoachFactory factory) {
            factory.CreateCoach().Command();
        }

        public static void main(String[] args) {
            create(new ACoachFactory());
            create(new CCoachFactory());
        }
    }
} } ``` - ### 封装   - 指利用抽象将数据和基于数据的操作封装在一起,使其构成一个不可分割的独立实体。    - 将对象的属性和行为封装起来,其载体就是类,类通常对客户隐藏其实现细节。 - 实例代码: ``` public class Husband {    /*
 * 对属性的封装
 * 一个人的姓名、性别、年龄、妻子都是这个人的私有属性
 */
private String name;
private String sex;
private int age;
private Wife wife;
/*
 * setter()、getter()是该对象对外开发的接口
 */
public String getName(){
    return name;
}
public String setName(String name){
    this.name=name;
}
public String getSex(){
    return sex;
}
public String setSex(String sex){
    this.sex=sex;
}

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

public void setWife(Wife wife) {
    this.wife=wife;
} } ``` - 封装确实可以使我们更容易地修改类的内部实现,而无需修改使用了该类的代码。 - 封装可以对成员变量进行更精确的控制。 - ### lambda 表达式   - 一种 `lambda` 表达式形式:参数, 箭头(->) 以及一个表达式。如果代码要完成的计算无法放在一个表达式中,就可以像写方法一样,把这些代码放在 {}中, 并包含显式的 `return`语句 ``` (String first, String second) -> //()内为参数 { //需要完成的计算代码 if (first.length() < second.length())      return -1; else if (first.length() > second.length())     return 1; else     return 0; } ``` - 即使 lambda 表达式**没有参数**, 仍然要提供空括号,就像无参数方法一样: ``` () -> {   for(i=0,i<=100,i++)System.out.println(i);  } ``` - ### 枚举类    - 枚举类型下的实例对象是其类所包含(拥有)的   - 若你创建了Season这个类,那么其下就有春(SPRING),夏(SUMMER),秋(AUTUMN),冬(WINTER),便要维护他们。 ``` enum SeasonEnum{ //枚举季节类
SPRING("春天"),SUMMER("夏天"),AUTUMN("秋天"),WINTER("冬天");

private String chinese;
SeasonEnum(String chinese){ //构造方法
    this.chinese=chinese; //调用this关键字
}
public String getchinese(){
    return chinese;
} } public class Test {
public static void main(String[] args) {
    String summer = "SUMMER";
    SeasonEnum season1 = SeasonEnum.SPRING;
    System.out.println(season1.getchinese());
} } ```  ``` enum SeasonEnum{ //枚举季节类
SPRING,SUMMER,AUTUMN,WINTER; } public class Test {
public static void main(String[] args) {
    String summer="SUMMER";
    SeasonEnum season1=SeasonEnum.valueOf(summer); //使用valueOf,获取SUMMER的枚举类型
    SeasonEnum season2=SeasonEnum.SPRING; //直接初始化
    switch (season1){
        case SPRING:
            System.out.println("春天");
            break;
        case SUMMER:
            System.out.println("夏天");
            break;
        case AUTUMN:
            System.out.println("秋天");
            break;
        case WINTER:
            System.out.println("冬天");
            break;
    }
} } ```
集合类型 描述
ArrayList 一种可以动态增长和缩减的索引序列
LinkedList 一种可以在任何位置进行高效地插人和删除操作的有序序列
ArrayDeque 一种用循环数组实现的双端队列
HashSet 一种没有重复元素的无序集合
TreeSet 一种有序集
EnumSet 一种包含枚举类型值的集
LinkedHashSet 一种可以记住元素插人次序的集
PriorityQueue 一种允许高效删除最小元素的集合
HashMap 一种存储键/值关联的数据结构
TreeMap 一种键值属于枚举类型的映射表
EnumMap 一种键值属于枚举类型的映射表
LinkedHashMap 一种可以记住键 / 值项添加次序的映射表
WeakHashMap 一种其值无用武之地后可以被垃圾回收器回收的映射表
IdentityHashMap 一种用==而不是equals()来比较键的映射表

线程全生命周期

实现Runnable接口的方式:

Thread类中的方法:

线程同步上来看,无论synchronized还是Lock,他们的底层都是通过传入唯一的锁对象来实现线程同步的。 从线程通信来看,synchronized的线程只能实现两个线程之间的通信,但是Condition却可以实现更多线程之间的通信。

接口/类 功能说明
Connection 数据库连接, 用于执行SQL语句
DriverManager 数据库驱动管理类,用于加载和卸载各种驱动程序,并建立于数据库的连接
Statement 此接口用于执行SQL语句并将数据检索到ResultSet
PreparedStatement 此接口用于执行预编译的SQL语句
ResultSet 结果集接口,提供检索SQL语句返回数据的各种方法
CallableStatement 此接口用于执行SQL存储过程的语句

primaryStage.setScene(new Scene(root)); primaryStage.show(); ```