Java - 面向对象

关于Java

1.JDK与JRE

JDK:java开发工具包,包含了java的开发工具(编译工具、打包工具等)和JRE
JRE:java运行环境,包括java虚拟机和java程序所需的核心类库等

2.
在一个java源文件中可以声明多个class
但最多只能有一个类声明为public,并且要求声明为public的类的类名必须与源文件名相同
如果文件中只有一个类,文件名必须与类名一致
如果文件中不止一个类,且没有public类,文件名可与任一类名一致

java源程序(.java)要先编译成与平台无关的一个或多个字节码文件(.class)
字节码文件的文件名与java源文件中的类名相同
字节码文件再通过java虚拟机解释成机器码运行
编译格式:javac 源文件名.java
运行格式:java 类名

3.文档注释

格式:
/**
    @author 指定java程序的作业
    @version 指定源文件的版本
*/

注释内容可以被JDK提供的工具javadoc所解析
生成一套以网页文件形式体现的该程序的说明文档
操作方式(命令行下):
javadoc -d 生成文件名 -author -version 文件名.java

4.
程序的入口是main()方法,格式是固定的:
public static void main(String[] args){

}

5.输出语句

System.out.println():先输出数据,再换行
System.out.print():只输出数据

基础知识

1. 命名规范

包名:多单词组成时所有字母都小写,xxxyyyzzz
类、接口名:多单词组成时,所有单词的首字母大写,XxxYyyZzz
变量、方法名:多单词组成时,第一个单词首字母小写,其余单词首字母大写,xxxYyyZzz
常量名:所有字母都大写。多单词时每个单词用下划线连接,XXX_YYY_ZZZ

2. 数据类型

整型:
byte(1字节) -128~127
short(2字节)
int(4字节)
long(8字节)
定义long型变量,必须以 l / L 结尾,例如:long l = 3414233213L

浮点型:
float(4字节):表示数值的范围比long还大
double(8字节)
定义float型变量,必须以 f / F 结尾,例如:float f = 12.3F

布尔型:
boolean:只能取两个值之一(true/false)
与C语言不同,true不代表非0,false不代表0

String类:
String属于引用数据类型
定义String类型变量时,使用一对""
char型变量不能为空,String类型变量可以为空
String可以和8种基本数据类型变量做连接运算(+)
判断两个字符串a,b是否相等时,不能用==,应用a.equals(b)

3. 基本数据类型之间的运算规则

1.自动类型提升
当容量小的数据类型的变量与容量大的数据类型的变量做运算时,结果自动提升为容量大的数据类型
容量大小指,表示数的范围的大和小。例如,float容量大于long的容量
byte char short --> int --> long --> float --> double 
特别的,当byte char short三种类型的变量做运算时(包括与自身做运算),结果为int型

2.强制类型转换
自动类型提升运算的逆运算,可能导致精度损失
需要使用强转符:()

整型常量,默认类型为int型
浮点型常量,默认类型为double型

4. 进制

二进制:0,1,满2进1,以0b或0B开头
十进制:0-9,满10进1
八进制:0-7,满8进1,以数字0开头表示
十六进制:0-9及A-F,满16进1,以0x或0X开头表示,此处的A-F不区分大小写

二进制有如下三种形式:
原码:直接将一个数值转换为二进制,最高位是符号位
正数的原码、反码、补码相同
负数的反码:对原码按位取反,最高位不变
负数的补码:其反码+1

计算机以二进制补码的形式保存所有整数

5. 运算符

1.取余运算
%:结果的符号与被模数的符号相同

2.自增、自减运算(++ --)
自增1自减1不会改变变量本身的数据类型
eg.
short s = 10;
s++;
s仍然为short型

3.赋值运算符(= += -= *= /= %=)
支持连续赋值
eg.
int i, j;
i = j = 10;

+= -= *= /= %=不会改变变量本身的数据类型
eg.
short s = 10;
s += 2;
s仍然为short型

4.比较运算符
比较运算符的结果是boolean型

5.逻辑运算符
逻辑运算符操作的都是boolean型变量
&:逻辑与
&&:短路与
|:逻辑或
||:短路或

6.位运算符
位运算符操作的都是整型数据
<<:在一定范围内,每左移1位,相当于*2(符号可能发生变化)
>>:在一定范围内,每右移1位,相当于/2
>>>:无符号右移,被移位二进制最高位无论是0或1,空缺位都用0补
&
|
^
~

7.三元运算符
结构:(条件表达式)? 表达式1 : 表达式2
条件表达式的结果为true,运算后的结果是表达式1;反之,结果是表达式2
三元运算符要求必须返回一个结果,且结果必须被使用
表达式1和表达式2的结果可以被统一为一个类型

如果程序既可以使用三元运算符,又可以使用if-else,则优先选择三元运算符(简洁、执行效率高)

6. 从键盘获取不同类型的变量

实现步骤:
1.导包:import java.util.Scanner;
2.Scanner的实例化:Scanner scan = new Scanner(System.in);
3.调用Scanner类的相关方法(next() / nextXxx()),来获取指定类型的变量

对于char型的获取,Scanner没有提供相关的方法,只能获取一个字符串

7. 分支结构

switch-case
格式:
switch(表达式){
    case 常量1:
        执行语句1;
        //break;

    case 常量2:
        执行语句2;
        //break;
    
    ...
    
    default:
        执行语句n;
        //break;
}

根据switch表达式中的值,依次匹配各个case中的常量
一旦匹配成功,则进入相应case结构,调用其执行语句
调用完执行语句后,仍然继续向下执行其他case结构中的执行语句
直到遇到break关键字或此switch-case结构末尾

switch结构中的表达式,只能是如下的6种数据类型之一:
byte short char int 枚举类型 String类型

如果switch-case结构中多个case的执行语句相同,则可以考虑合并

8. 数组

数组是引用数据类型

一维数组
1.声明和初始化
int[] ids; //声明
//静态初始化:数组的初始化和数组元素的赋值操作同时进行
ids = new int[]{1,2,3,4};
//动态初始化:数组的初始化和数组元素的赋值操作分开进行
String[] names = new String[5];

数组一旦初始化完成,其长度就确定了

2.如何获取数组的长度
通过数组的属性length获取:数组名.length

3.数组元素的默认初始化值
数组元素是整型:0
浮点型:0.0
char型:0或'\u0000',而非'0'
boolean型:false
数组元素是引用数据类型:null,而非"null"

二维数组
1.声明和初始化
//静态初始化
int[][] arr1 = new int[][]{{1,2,3},{4,5},{7,8,9}};
int[][] arr1 = {{1,2,3},{4,5},{7,8,9}}; //类型推断
//动态初始化
String[][] arr2 = new String[3][2];
String[][] arr3 = new String[3][];

2.如何获取数组的长度
arr1.length //3
arr1[1].length //2

3.数组元素的默认初始化值
规定:二维数组分为外层数组的元素和内层数组的元素
      int[][] arr = new int[4][3];
      外层元素:arr[0],arr[1]等
      内层元素:arr[0][0]等
针对初始化方式一,比如,int[][] arr = new int[4][3];
    外层元素的初始化值:地址值
    内层元素的初始化值:与一维数组初始化情况相同
针对初始化方式二,比如,int[][] arr = new int[4][];
    外层元素的初始化值:null
    内层元素的初始化值:不能调用,否则报错
java.util.Arrays:操作数组的工具类,里面定义了很多操作数组的方法
eg.
boolean equals(int[] a, int[] b)  判断两个数组是否相等
String to String(int[] a)  输出数组信息
void fill(int[] a, int val)  将指定值填充到数组之中
void sort(int[] a)  对数组进行排序
int binarySearch(int[] a, int key)  对排序后的数组进行二分法检索指定的值

9. 排序算法

从平均时间而言,快速排序最佳O(nlog2n),但在最坏情况下时间性能不如堆排序和归并排序

面向对象 

1. 类和对象

类:对一类事物的描述,是抽象的、概念上的定义
对象:是实际存在的某类事物的每个个体,因而也称为实例(instance)

面向对象程序设计的重点是类的设计
设计类,就是设计类的成员

常见的类的成员:
属性(成员变量、field、域、字段)
方法(成员方法、函数、method)

类和对象的使用:
1.创建类,设计类的成员
  class Person{
    ...
  }
2.创建类的对象:
  Person p = new Person();
3.通过 对象.属性 / 对象.方法 调用对象的结构

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

2. 类的成员

属性

属性和局部变量的不同

1.在类中声明的位置不同
属性:定义在类的一对{}内
局部变量:声明在方法内、代码块内、构造器内部的变量,或方法形参、构造器形参

2.关于权限修饰符的不同
属性:可以在声明时,通过使用权限修饰符指明其权限
常用的权限修饰符:private public 缺省(不加) protected
局部变量:不可以使用权限修饰符

3.默认初始化值
属性:根据其类型,都有相应的默认初始化值(与数组元素的相同)
局部变量:没有默认初始化值。在调用局部变量前,一定要显式赋值

4.在内存中加载的位置
属性:堆空间中(非static)
局部变量:栈空间

属性赋值的先后顺序 

1.默认初始化
2.显式初始化 / 在代码块中赋值
3.构造器中初始化
4.通过 对象.方法 或 对象.属性 的方式赋值

方法

1.方法的声明
权限修饰符 返回值类型 方法名(形参列表){
    方法体;
}

2.方法中可以调用当前类的属性或方法
  方法中不可以定义方法

3.方法的重载
在同一个类中,允许存在一个以上的同名方法(它们的参数个数或者参数类型不同)
eg.如下的两个方法也构成重载
public void getSum(String s, int i){
}
public void getSum(int i, String s){
}

判断是否是重载:与方法的权限修饰符、返回值类型、形参变量名、方法体都没有关系

可变个数的形参

1.可变个数形参的格式:数据类型 ... 变量名
2.当调用具有可变个数形参的方法时,传入的参数个数可以是0个/1个/...
3.具有可变个数形参的方法与本类中方法名相同,形参不同的方法之间构成重载
  具有可变个数形参的方法与本类中方法名相同,形参类型也相同的数组之间不构成重载 
4.在方法体中,可以把传入的可变个数形参看作相同类型的数组进行操作        
5.方法的形参中,最多只能声明一个可变个数形参,且只能声明在末尾
eg.
public void show(String ... strs){
}

方法参数的值传递机制 

引用数据类型的变量要么是null,要么是地址值(含变量的数据类型)

值传递机制:
如果参数是基本数据类型,此时实参赋给形参的是实参真实存储的数据值
如果参数是引用数据类型,此时实参赋给形参的是实参存储数据的地址值

构造器

构造器的作用:
创建对象
初始化对象的信息

1.如果没有显式定义类的构造器,则系统默认提供一个空参的构造器
2.定义构造器的格式:权限修饰符 类名(形参列表){}
3.一个类中定义的多个构造器,彼此构成重载
4.一旦显式定义了类的构造器之后,系统将不再提供默认的空参构造器

代码块 

1. 作用:初始化类、对象

2. 只能用static修饰

3. 静态代码块

内部可以有输出语句

随着类的加载而执行,且只执行一次

作用:初始化类的信息

如果一个类中定义了多个静态代码块,则按照声明的先后顺序执行

静态代码块内只能调用静态的属性、静态的方法,不能调用非静态的结构

4. 非静态代码块

内部可以有输出语句

随着对象的创建而执行(每创建一个对象就执行一次)

作用:在创建对象时,对对象的属性等进行初始化

如果一个类中定义了多个非静态代码块,则按照声明的先后顺序执行

非静态代码块内可以调用静态的结构和非静态的结构

内部类 

1. 将一个类A声明在另一个类B中,则A是内部类,B是外部类

2. 内部类的分类

        2.1 成员内部类

                一方面,作为外部类的成员:

                        a. 可以调用外部类的结构

                        b. 可以被static修饰

                        c. 可以被4种不同的权限修饰符修饰

                另一方面,作为一个类

                        a. 类内可以定义属性、方法、构造器

                        b. 可以被final、abstract修饰

        2.2 局部内部类

3. 如何实例化成员内部类的对象

//Dog为Person类中静态的成员内部类
Person.Dog dog = new Person.Dog();

//Bird为Person类中非静态的成员内部类
Person p = new Person();
Person.Bird bird = p.new Bird();

4. 如何在成员内部类中区分调用外部类的结构

//在Person类的内部类中。调用Person类的属性name
Person.this.name

5. 开发中局部内部类的使用

//返回一个实现了Comparable接口的类
public Comparable getComparable(){    
    class MyComparable implements Comparable{        
        @override
        public int compareTo(Object o) {
            return 0
        }    
    }    
    return new MyComparable();
}

3. 内存的简化结构

堆:存放对象实例、数组
栈(虚拟机栈):存储局部变量
方法区:存储类信息、常量、静态变量等

4. 面向对象的特征

封装与隐藏

封装性的设计思想
隐藏对象内部的复杂性,只对外公开简单的接口。便于外界调用,从而提高系统的可扩展性、可维护性

封装性的体现
1.将类的属性xxx私有化(private)
  同时提供公共(public)方法来获取(getXxx)和设置(setXxx)该属性的值
2.不对外暴露私有的方法
3.单例模式
封装性的体现,需要权限修饰符来配合
1.java规定的4种权限(从小到大):private 缺省 protected public
2.4种权限都可以用来修饰类的内部结构:属性、方法、构造器、内部类
                  修饰类,只能使用缺省、public

this关键字的使用 

1.this可以用来修饰属性、方法、构造器

2.修饰属性和方法时,this可以理解为当前对象或当前正在创建的对象
  2.1 如果方法的形参和类的属性同名,必须显式地通过this.变量的方式来表明此变量是属性,而非形参
  2.2 构造器中同理

3.this调用构造器
  1.在类的构造器中,可以显式地通过 this(形参列表) 的方式调用本类中指定的其他构造器
  2.构造器中不能通过 this(形参列表) 方式调用自己
  3.规定:this(形参列表) 必须声明在当前构造器的首行
    构造器内部最多只能声明一个 this(形参列表)

package关键字的使用

1.包有利于更好地实现项目中类的管理
2.使用package声明类或接口所属的包时,声明在源文件的首行
3.包,属于标识符,遵循标识符的命名规则,规范(xxxyyyzzz),应见名知意
4.每 . 一次,就代表一层文件目录

同一个包下,不能命名同名的接口、类
不同的包下,可以命名同名的接口、类

import关键字的使用

import:导入
1.使用import结构导入指定包下的类、接口
2.声明在包和类的声明之间
3.import xxx.*:表示导入xxx包下的所有结构(除xxx子包下的结构)
4.如果使用的类或接口是java.lang包下定义的,则可以省略import结构
5.如果使用的类或接口是本包下定义的,则可以省略import结构
6.如果使用了不同包下同名的类,则至少有一个类需要以全类名的方式显示
7.import static:导入指定类或接口中的静态结构(属性或方法)

继承性 

继承性的好处:
1.减少代码冗余,提高代码的复用性
2.便于功能的扩展
3.为之后多态性的使用提供了前提

格式:
class A extends B{}
A:子类、派生类 subclass
B:父类、超类、基类、superclass

一旦子类继承父类,子类就获取了父类中声明的所有属性和方法
由于封装性的影响,子类不能直接调用父类中声明为private的属性和方法

子类继承父类后,还可以声明自己特有的属性或方法,实现功能拓展

关于继承性的规定:
1.一个类可以被多个子类继承
2.java中类的单继承性:一个类只能有一个父类
3.子父类是相对概念
4.直接父类:子类直接继承的父类
  间接父类:子类间接继承的父类
5.子类继承父类后,就获取了直接父类以及所有间接父类中声明的属性和方法

如果没有显式地声明一个类的父类,则该类继承java.lang.Object类
所有的java类(除java.lang.Object类)都直接或间接地继承java.lang.Object类

方法的重写(override / overwrite) 

1.重写:子类继承父类以后,可以对父类中同名同参数的方法,进行覆盖操作
2.规定
  a.子类重写的方法的权限修饰符不小于父类被重写的方法的权限修饰符
    特殊情况:子类不能重写父类中声明为private权限的方法
  b.父类被重写的方法的返回值类型是void,则子类重写的方法的返回值的类型只能是void
    父类被重写的方法的返回值类型是A类型,则子类重写的方法的返回值的类型可以是A类或A类的子类
  c.子类重写的方法抛出的异常类型不大于父类被重写的方法抛出的异常类型
  d.子类和父类中同名同参数的方法要么都声明为非static(考虑重写),要么都声明为static(不是重写)

super关键字的使用

1.super理解为:父类的
2.super可以用来调用属性、方法、构造器
3.调用属性和方法
  a.在子类的方法或构造器中,可以通过super.属性 / super.方法显式调用父类中声明的属性或方法
    通常情况下,习惯省略super
  b.当子类和父类中定义了同名的属性时,要想在子类中调用父类中声明的属性,必须使用super.属性
  c.当子类重写了父类中的方法后,要想在子类中调用父类中被重写的方法,必须使用super.方法
4.调用构造器
  a.可以在子类的构造器中显式使用super(形参列表),来调用父类中声明的指定构造器
  b.super(形参列表)使用时必须声明在子类构造器的首行
  c.若在构造器的首行没有显式声明this(形参列表)和super(形参列表),则默认调用父类的空参构造器

 子类对象实例化的全过程

1.从结果上看:
  子类继承父类以后,就获取了父类中声明的属性和方法
  创建子类的对象时,在堆空间中就会加载所有父类中声明的属性

2.从过程上看:
  当通过子类的构造器创建对象时,一定会直接或间接地调用其父类的构造器,进而调用其父类的父类的构造器...
  ...直到调用了java.lang.Object类中空参的构造器为止。正因为加载过所有的父类结构,所以才可以看到内存中有父类的结构,子类对象才可以考虑进行调用

3.虽然创建子类对象时,调用了父类的构造器,但只创建过一个对象,即new的子类对象

多态性 

1.对象的多态性:父类的引用指向子类的对象(子类的对象赋给父类的引用)
2.多态的使用:虚拟方法调用
  有了对象的多态性后,在编译期只能调用父类中声明的方法,但在运行期实际执行的是子类重写后的方法
  总结:编译看左边,运行看右边
3.多态性的使用前提:类的继承关系 方法的重写
4.对象的多态性只适用于方法,不适用于属性(编译和运行都看左边)

方法的重载与重写

从编译和运行的角度看:
重载不表现多态性,在方法调用前,编译器就已经确定了所要调用的方法(早绑定/静态绑定)
重写可以表现多态性,只有等到方法调用时,解释运行器才会确定要调用的具体方法(晚绑定/动态绑定)

向下转型

如何才能调用子类特有的属性和方法?
向下转型:使用强制类型转换符(可能出现ClassCastException)

instanceof关键字

类的实例包含本身的实例,以及所有直接或间接子类的实例
a instanceof A:判断对象a是否是类A的实例。若是,返回true;否则返回false

使用情景
为了避免向下转型时出现ClassCastException异常,在向下转型前,先进行instanceof的判断,
若返回true,则可以进行;否则不可以进行

如果a instanceof A返回true,则a instanceof B也返回true,其中,类B是类A的父类

5. JavaBean 

JavaBean是一种用Java语言写成的可重用组件
指符合如下标准的Java类:
1.类是公共的
2.有一个无参的公共的构造器
3.有属性,且有对应的get、set方法

6. Object类的使用

java.lang.Object类
1.Object类是所有Java类的根父类
2.如果在类的声明中未使用extends指明其父类,则默认父类为Object类
3.Object类中的属性与方法具有通用性
  属性:无
  方法:equals() / toString() / getClass() / hashCode() / clone() / finalize()
        / wait() notify() notifyAll()

4.Object类只声明了一个空参构造器

== 和 equals() 的区别

==:运算符
1.可以使用在基本数据类型变量和引用数据类型变量中
2.基本数据类型:比较两个变量保存的数据是否相等(不一定类型要相同)
  引用数据类型:比较两个对象的地址值是否相同,即两个引用是否指向同一个对象实体

equals()方法的使用
1.只能适用于引用数据类型
2.Object类中定义的equals()和==的作用是相同的
3.String、Date、File、包装类等都重写了Object类中的equals()方法
  重写后,比较的是两个对象的“实体内容”

4.重写equals()方法示例
比较两个圆的半径是否相等:
public boolean equals(Object obj){
    if(this == obj) return true;    
    if(obj instanceof Circle){       
        Circle c = (Circle)obj;
        return this.radius == c.radius;
    }
    else return false;
}

toString()的使用

1.当我们输出一个对象的引用时,实际上就是调用当前对象的toString()
2.String Data File 包装类等都重写了Object类中的toString()
  使得在调用对象的toString()时,返回“实体内容”信息

7. 包装类的使用 

基本数据类型、包装类、String三者之间的转换

1. 基本数据类型 --- 包装类:调用包装类的构造器

int num = 10;
Integer in1 = new Integer(num);
Integer in1 = new Integer("123");

2. 包装类 --- 基本数据类型:调用包装类的xxxValue() 

Integer in = new Integer(12);
int i = in.intValue();

JDK5.0新特性:自动装箱与自动拆箱

自动装箱:基本数据类型 --- 包装类

int num = 10;
Integer in = num;

自动拆箱:包装类 --- 基本数据类型 

Integer in = new Integer(1);
int num = in;

3. 基本数据类型、包装类 --- String类型:调用String重载的valueOf(参数)

int num = 10;
String str1 = String.valueOf(num);
Integer in = new Integer(10);
String str2 = String.valueOf(in);

4. String类型 --- 基本数据类型、包装类:调用包装类的parseXxx(String s)

String str = "123";
int num = Integer.parseInt(str);

Tips

Integer内部定义了IntegerCache结构,其中定义了Integer[ ],保存了-128~127的整数。如果使用自动装箱的方式,当给Integer赋值的范围在-128~127时,可以直接使用该数组中的元素,不再需要new

目的:提高效率

8. static关键字的使用 

1. static:静态的

2. static可以用来修饰属性、方法、代码块、内部类

3. 使用static修饰属性:静态变量(类变量)

    3.1 属性按是否用static修饰分为静态属性与非静态属性(实例变量)

          实例变量:创建一个类的多个对象时,每个对象都独立拥有一套类中的非静态属性

          静态变量:创建一个类的多个对象时,多个对象共享同一个静态变量

    3.2 其他说明:

          静态变量随着类的加载而加载,可以通过 类.静态变量 的方式调用

          静态变量的加载早于对象的创建

          静态变量存在方法区的静态域中,且只存在一份

4. 使用static修饰方法:静态方法

    随着类的加载而加载,可以通过 类.静态方法 的方式调用

    静态方法中只能调用静态的方法或属性

5. 注意点

在静态方法内,不能使用this和super

6.

如何确定一个属性是否要声明为static?

当这个属性可以被多个对象所共享,不会随着对象的不同而不同时

类中的常量也常常声明为static

如何确定一个方法是否要声明为static?

操作静态属性的方法

工具类中的方法,如Math、Arrays、Collections

9. final关键字的使用

1. final 可以用来修饰的结构:类、方法、变量

2. final 用来修饰一个类:此类不能被其他类继承

3. final 用来修饰方法:表明此方法不可以被重写

4. final 用来修饰变量:此时的变量实际上是常量

    4.1 final 修饰属性,可以赋值的位置:显式初始化、代码块中初始化、构造器中初始化

    4.2 final修饰局部变量:特别是用final修饰形参时,表明该形参是一个常量。只能在方法体内使用该形参,不能重新赋值

5. static final 修饰属性:表明该属性为全局常量

10. 抽象方法与抽象类

abstract关键字的使用

1. abstract 可以用来修饰的结构:类、方法

2. abstract 修饰类:抽象类

        a. 此类不能实例化

        b. 抽象类中一定有构造器,当子类实例化时调用

        c. 开发中,都会提供抽象类的子类,让子类对象实例化,完成相应的操作

3. abstract 修饰方法:抽象方法

        a. 抽象方法只有方法的声明,没有方法体

        b. 包含抽象方法的类,一定是一个抽象类

            抽象类中可以没有抽象方法

        c. 若子类重写了父类中所有的抽象方法,该子类才可以实例化

            若子类没有重写父类中所有的抽象方法,则该子类也是一个抽象类,需要用abstract修饰

4. 注意点

        a. abstract 不能用来修饰属性、构造器等结构

        b. abstract 不能用来修饰私有方法、静态方法、final 修饰的方法、final 修饰的类     

创建抽象类的匿名子类对象

//Person为抽象类 eat()为该类中的抽象方法
Preson p = new Person(){
    
    @override
    public void eat(){
        System.out.println("吃东西");
};

11. 接口

接口的使用

1. 使用 interface 来定义接口

2. Java中接口和类是并列的两个结构

3. 定义接口中的成员

    3.1 JDK7 及以前,只能定义全局常量和抽象方法

          a. 全局常量:public static final(书写时可以省略不写)

          b. 抽象方法:public abstract

    3.2 JDK8:还可以定义静态方法、默认方法

          a. 静态方法:public static

                                接口中定义的静态方法只能通过接口来调用

          b. 默认方法:public default        

                                实现类的对象可以调用接口中的默认方法

                                实现类可以重写接口中的默认方法

                                如果子类继承的父类和实现的接口中声明了同名同参数的方法,那么在子类没有重写此方法的情况下,默认调用父类中同名同参数的方法(类优先原则)

                                如果实现类实现了多个接口,而这多个接口中定义了同名同参数的默认方法,那么在实现类没有重写此方法的情况下,会报错(接口冲突)       

4. 接口中不能定义构造器,即接口不可以实例化

5. Java开发中,接口通过让类去实现(implements)的方式来使用

    如果实现类覆盖了接口中所有抽象方法,则该实现类可以实例化。否则,该实现类仍为一个抽象类     

6. Java一个类可以实现多个接口,弥补了Java单继承性的局限性

    格式:class AA extends BB implements CC, DD, EE

7. 接口与接口之间可以继承,且可以多继承

8. 接口的具体使用体现了多态性

9. 接口,实际上可以看作是一种规范

10. 开发中体会面向接口编程         

常用方法

 1. 获取一个随机数

Math.random()返回一个double型数值:[0.0, 1.0)
例如,随机生成一个两位数:
int value = (int)(Math.random() * 90 + 10);

 2. 获取当前时间

System.currentTimeMillis()返回一个long型数值:
代表当前时间距离1970-01-01 00:00:00的毫秒数

可以通过调用两次该方法来计算执行某一段程序所需的时间

3. 计算开方

Math.sqrt(double a);
返回一个double型数值

Eclipse常用快捷键 

https://blog.csdn.net/qq_53913035/article/details/123608955

单元测试 

Java中的JUnit单元测试

步骤(Eclipse):

1. 选中当前工程 - 右键选择:build path - add libraries - JUnit 4 - 下一步

2. 创建Java类,进行单元测试

    Java类的要求:public 且 提供无参构造器

3. 此类中声明单元测试方法:public 无返回值 无形参

4. 单元测试方法上需要声明注解:@Test

    并:import org.junit.Test

5. 声明好单元测试方法后,就可以在方法体内测试相关的代码

6. 写完代码以后,左键双击单元测试方法名,右键:run as - JUnit Test

说明:

1. 如果执行结果没有任何异常:绿条

2. 如果执行结果出现异常:红条

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值