Java面向对象第二周预习
一、包
1.1建包
package com.test.domain;
public class Student{
.....
}
- 建包语句必须在第一行
- 建包的语法格式:package公司域名倒写.技术名称。建议全部英文小写,且具备意义。
1.2导包
import 包名.类名
import com.test.domain.Student;
public class Test{
.....
}
- 相同包下的类可以直接访问,不同包下的类必须导包才能使用。
- 一个类中需要使用到不同类,而这两个类的名称是一样的,那么默认只能导入一个类,另一个类要带包名访问
二、抽象类
2.1抽象类和抽象方法
用abstract关键字修饰的类叫做abstract类(抽象类)。
abstract class A{
......
}
用abstract关键字修饰的方法叫做abstract方法(抽象方法)。
abstract class A{
int add(int a,int b){
return a+b;
}
abstract int minus(int a,int b);
}
- 只有抽象类中才能有抽象方法,抽象类中也可以有非抽象方法
- 不能用final和abstract同时修饰一个方法或类
- 不能用static和private修饰抽象方法
- 抽象方法只允许声明不允许实现(没有方法体)
2.2抽象类和抽象方法的利用
抽象类不能用new创建对象
需要将抽象类转化为上转型对象调用。
抽象类的子类
如果一个非抽象子类是某个抽象类的子类,那么他必须重写父类的抽象方法,即去掉抽象方法的abstract修饰,并给出方法体,这就是为什么不同时用final和abstract修饰一个方法或类。
如果一个抽象子类是某个抽象类的子类,那么他可以继承也可以重写父类的抽象方法。
理解抽象类的使用
抽象类可以封装子类的共有的行为标准,将该行为标准用抽象方法来表示,
子类通过重写抽象父类的抽象方法来给出行为标准的具体行为,
将父类转化为子类的上转型对象调用子类重写的方法。
三、接口
3.1接口的定义
用关键字interface定义一个接口
interface inter{
......
}
3.2接口的内容
常量与抽象方法
接口用来声明规则,定义行为标准,其中能含有常量与抽象方法
interface inter{
public static final int max = 100; //max是常量
public abstract void add(); //add是抽象方法
/*public static int MAX;
错误,MAX是变量
*/
/*public void ADD(){
....
}
错误,ADD是非抽象方法
*/
}
- public和abstract修饰符可以省略
实例方法
接口中可以用default关键字修饰带方法体的实例方法(不可以定义default的static方法),default方法的访问权限必须是public(可以省略)。
interface inter{
public default int add(int a,int b){
return a+b;
}
//用default修饰的接口中的实例方法
}
注意:不可以省略default
static方法与private方法
可以用static与private关键字在接口体中定义static方法与private方法。
接口中没有构造方法
类实现接口调用的构造方法是object类中的。
3.3实现接口
类实现接口
一个类在类声明中使用关键字implements声明该类实现一个或多个接口,实现多个接口用逗号隔开接口名。
class A implements Com,Apple{
......
}
重写接口中的方法
类实现接口可以看作类是接口的一个子类,因此:
- 一个类实现了某个接口就自然拥有了接口中的常量、default方法,也可以重写default方法。
- 一个非抽象类实现了某个接口,那么则需要重写接口中的所有抽象方法
- 一个抽象类实现了某个接口,可以选择重写或直接拥有该接口的抽象方法
注意:抽象类可以不重写接口的抽象方法。
使用接口中的常量和static方法
类实现某接口但类不拥有接口的static方法和private方法
类中可以用接口名访问和调用接口中的常量和static方法。
Com.max; //调用Com接口中的常量
Com.f(); //访问Com接口static方法
3.4接口回调
接口回调类似子类继承中的上转型对象
接口回调指的是可以把实现某一接口的类创建的对象的引用赋值给该接口声明的接口变量,此时该接口变量可以调用被该类实现的接口方法以及接口提供的default方法或类重写的default方法。
//Com是一个接口,ImpleCom是实现Com的类
Com com;
//声明一个com变量
//此时com是一个空接口
ImpleCom object = new ImpleCom();
//创建一个ImpleCom对象object并分配内存
com = object;
//将object的引用赋值给com,实现接口回调
3.5函数接口与Lambda表达式
函数接口
如果一个接口中只有一个abstract方法,称这样的接口是单接口,也称函数接口。
Lambda表达式
通常方法Sum,可以用Lambda表达式表现为一个匿名方法
//通常方法
int Sum(int a,int b){
return a+b;
}
//Lambda表达式
(int a,int b) ->{
return a+b;
}
//或者
(a,b) ->{
return a+b;
}
利用接口回调使用Lambda表达式
Lambda表达式主要用于单接口,声明接口变量,可以将Lambda表达式的方法的入口地址赋值给接口变量,那么该接口变量就能调用Lambda表达式实现接口中的方法,这一机制被称为接口回调Lambda表达式实现的接口方法。
public interface Com{
public abstract int Sum(int a,int b);
}
//定义Com接口含有Sum抽象方法
Com com = (a,b) ->{
return a+b;
}
//把Lambda表达式赋值给com使其能实现接口中的Sum方法
四、内部类与异常类
4.1内部类
内部类的定义
在一个类中定义的类就是内部类,而包涵内部类的类成为内部类的外嵌类。
class Outer{
// 内部类
class Inner{
......
}
}
内部类的创建
格式:外部类名.内部类名 对象名 = new 外部类对象().new 内部类对象();
Outer.Inner in = new Outer().new Inner();
内部类与外嵌类的关系
- 内部类中,访问外部类成员:直接访问,包括私有
- 外部类中,访问内部类成员:需要创建对象访问
- 内部类仅供它的外嵌类使用
静态内部类
有static修饰的成员内部类是静态内部类
class Outer{
static class Inner{
}
}
程序可以在其他类中调用static内部类创建对象,但static内部类不能操作外嵌类中的实例成员变量。
局部内部类
放在方法、代码块、构造器等执行体中
public A{
public void show(){
class B{
public void method(){
System.out.println("Hello!");
}
B b = new B();
b.method;
}
}
}
public Test{
public static void main(String[] args){
A a = new A();
a.show;
}
}
仅做了解
4.2匿名内部类
定义匿名内部类
匿名类就是一个类(接口)的子类,不能用匿名类声明对象,但可以直接用匿名类创建一个对象。
new 类名/接口(){
//new 类名() :代表继承这个类
//new 接口名() :代表实现这个方法
}
与接口有关的匿名内部类
当某个方法的参数是接口时,可以用接口名和类体组合创建一个匿名对象传递给方法的参数
class Test{
public static void main(String[] args){
useInter(new Inter(){ //不能用new创建接口对象,创建匿名类实现接口作为参数
@Override //类实现接口时要重写内部的抽象方法
public void show(){
System.out.println("show...i");
}
});
}
public static void useInter(Inter i){
i.show();
}
}
interface Inter{
void show();
}
用Lambda表达式代替匿名内部类
简化格式
(匿名内部类被重写方法的形参列表) -> {
被重写方法的方法体代码。
}
注:-> 是语法格式,无实际含义
与直接使用匿名内部类对比
class Test{
public static void main(String[] args){
useInter(new Inter(){
@Override
public void show(){
System.out.println("show...1");
}
});
useInter( () -> {
//重写方法无参
@Override
public void show(){
System.out.println("show...2");
}
//被重写方法的方法体代码
});
}
五、异常类
5.1异常
异常是代码在编译或者执行的过程中可能出现的错误。
异常的体系结构
- Throwable
- Error:严重级别错误
- Exception:异常类,程序常见错误
- 编译时异常、运行时异常
- 编译时异常没有继承RuntinmeException的异常,编译时就会出错
- 运行时异常:继承自RuntimeExpection的异常或其子类编译阶段不报错,运行可能报错
Java允许在定义方法时声明该方法调用过程中可能出现的异常,即允许方法在调用过程中抛出异常对象,终止当前方法的继续执行。
5.2try-catch语句
用try-catch语句处理异常,将可能出现的异常操作放在try-catch语句的try部分,try部分一旦抛出异常对象,或者调用某个可能抛出异常对象的方法,并且该方法抛出了异常对象,那么try部分将立刻结束执行,转而执行相应的catch部分。
try{
//包含可能发生异常的语句
}
catch(ExceptionSubClass1 e){
...
}
catch(ExceptionSubClass2 e){
...
}
各个catch参数中的异常类都是Exception的某个子类
5.3自定义异常类
可以拓展Exception或RuntimeException类定义自己的异常类
一个方法声明时可以用throws关键字声明要产生的若干个异常,并在该方法体中给出产生异常的操作,即用相应的异常类创建对象,并使用throw关键字抛出异常对象,导致该方法结束执行。
程序必须在try-catch语句中调用可能发生异常的方法。
public class AException extends Exception{//自定义异常类
String message;
public AException(int m, int n){ //构造方法
message="a与b都小于0,不符合要求。";
}
public String warnMess(){
return message;
}
}
public class B{
int B;
public void Test(int a,int b) throws AException{ //throws声明要产生的异常
if(a<0 && b<0)
throw new AException(a,b); //满足条件抛出异常
B = a + b;
System.out.println(getB());
}
public int getB(){
return B;
}
}
public class Test{
public static void main(String args[]){
B b = new B();
try{
b.Test(1,1);
b.Test(1,-1);
b.Test(-1,-1);
}
catch(AException e){
System.out.println(e.warnMess());//捕获异常
}
}
}
输出为:
2
0
a与b都小于0,不符合要求。
5.4断言语句
断言语句的格式
用关键字assert声明一个断言语句
assert booleanExpression;
assert booleanExpression:messageException;
断言语句的使用
当为第一种形式时,例如
assert num >= 0;
当booleanExpression的值为true即num大于零时,程序继续执行,否则程序立即结束执行。
当为第二种形式时,例如
assert num >= 0:"不能是负数";
当booleanExpression的值为true即num大于零时,程序继续执行,否则程序立即从断言语句处停止执行并输出messageException的值,即“不能是负数”,提示用户出现了怎样的问题。
六、包装类
6.1包装类
将基本数据类型,包装成类(变成引用数据类型)。
基本数据类型 | 引用数据类型 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
char | Character |
float | Float |
double | Double |
boolean | Boolean |
6.2如何包装
手动装箱
调用方法,手动将基本数据类型,包装成类。
以Integer类为例
public Integer (int value);// 通过构造方法(不推荐)
public static Integer valueOf(int i);//通过静态方法
int n = 10;
Integer i = new Integer(n);
Integer i = Integer.valueOf(n);
手动拆箱
调用方法,手动将包装类,拆成基本数据类型
public int intValue():以int类型返回该Integer的值
int n = 10;
Integer i = Integer.valueOf(n);
int m = i.intValue();
System.out.println(m);
//打印出10
自动拆装箱
从JDK5版本开始,出现了自动拆装箱(直接赋值):
int n = 10;
Integer i = n;
int m = i;
6.3为什么用包装类
包装类有许多static方法可以直接调用,如Integer中的toBinaryString(int i )转二进制等,使编写程序更方便
6.4StringBuffer与StringBuilder
Java提供了String、StringBuffer 和 StringBuilder 类来封装字符串,并提供了一系列操作字符串对象的方法。
StringBuffer与String的区别
String对象的字符序列是不能修改的,而StringBuffer类的对象的实体的内存空间可以自动改变大小,便于内存存放一个可变的字符序列。
创建StringBuffer类对象
StringBuffer strbuffer = new StringBuffer("这里是文字");
- StringBuffer有3个构造方法,StringBuffer()、StringBuffer(int size)、StringBuffer(String s)
- 第一个无参构造方法分配给该对象16个字符,当存放对象大于16个字符时实体的容量自动增加
- 第二个构造方法可以指定分配的字符个数,存放的对象大于size个字符时实体的容量自动增加
- 第三个构造方法可以指定分配该对象的实体的初始容量为参数的字符序列的长度加16
StringBuffer常用方法
方法声明 | 功能描述 |
---|---|
StringBuffer append(char c) | 添加字符到StringBuffer对象中末尾 |
StringBuffer insert(int offset,String str) | 在StringBuffer对象中的offset位置插入字符串 |
StringBuffer deleteCharAt(int index) | 移除StringBuffer对象中指定位置的字符 |
StringBuffer delete(int start,int end) | 删除StringBuffer对象中指定范围的字符或字符串 |
StringBuffer replace(int start,int end,String s) | 将StringBuffer对象中指定范围的字符或字符串用新的字符串s进行替换 |
void setCharAt(int index,char ch) | 修改指定位置index的字符 |
String toString() | 返回StringBuffer缓冲区中的字符串对象 |
StringBuffer reverse() | 将此StringBuffer对象用其反转形式取代 |
String与StringBuffer与StringBuilder的区别
- String:不可变字符串
- StringBuffer:可变字符串、效率低、线程安全
- StringBuilder:可变字符序列、效率高、线程不安全
StringBuilder有与StringBuffer相同的一组方法,多数情况下两者可以代替使用。
多线程环境使用StringBuffer,单线程环境使用StringBuilder会有更好的性能。
6.5BigDecimal类
用于解决小数运算中,出现的不精确的问题
创建BigDecimal对象
public BigDecimal(double val)//不推荐,无法保证小数运算的精确
public BigDecimal(String val)
public static BigDecimal valueOf(double val)
------------------------------------------------
BigDecimal bd = new BigDecimal(0.1);//不推荐,无法保证小数运算的精确
BigDecimal bd = new BigDecimal("0.1");
BigDecimal bd = BigDecimal.balueOf(0.1);
BigDecimal常用方法
方法声明 | 功能描述 |
---|---|
public BigDecimal add(BigDecimal b) | 加法a+b |
public BigDecimal subtract(BigDecimal b) | 减法a-b |
public BigDecimal multiply(BigDecimal b) | 乘法a*b |
public BigDecimal divide(BigDecimal b) | 除法a/b |
public BigDecimal divide(另一个BigDecimal对象,精确几位,舍入模式) | 除法a/b |
注意:除不尽会出现异常。
- RoundingMode.UP 进一法
- RoundingMode.DOWN 去尾法
- RoundingMode.HALF_UP 四舍五入