Java接口以及static和final关键字
一、static
二、final
三、让final元素可以初始化,不用固定赋值
四、接口
五、抽象方法
六、接口能够创建对象吗(匿名内部类)
七、另一实例,开锁
一、static
static代表静态的,唯一
主要有下面两种形式:
二、final
final代表最终形态的、不可变
-
修饰属性: 定义常量,不可修改,且需要定义时赋值
-
修饰方法: 不能被子类重写
-
修饰类:不能有子类,不能被继承
修饰属性如果不复制便会报错:
注意:并不是说必须在id后面直等于一个值进行赋值,只要有相应赋值的代码就可以,这也是下面第三大节我们要讲述的。
既然static代表唯一,final代表不可变,那么我们可以用static final结合来定义一个既不能修改又只能存在一个的常量,例如数学Math中的常量PI
三、让final元素可以初始化,不用固定赋值
我们很可能有这种情况,想为每个用户创建唯一的id,但是使用final又要固定赋值,不是我们想要的自增效果,那么如何来实现呢?
- 代码块:另定义一个static变量专门用来给id赋值,可以使用
代码块
来每次创建对象对id进行初始化
- 构造函数:在构造方法中直接给id赋值。
代码块:
构造函数:
我们测试一下第一种方式,因为第二种是按照我们个人随意制定,而第一种每次自动赋值。
输出:
可以看到进行了自动赋值,这也符合我们的需求。
四、接口
之前我们是用过ActionListener 接口,用来按钮点击处理,发现它有一个方法,且没有方法体,这是接口的一大特点。
-
定义: interface /class
-
1: 接口中所有的属性变量,都默认由static final 关键字修饰,即不可修改
-
2: 接口中的方法,都默认为没有方法体的方法 ,抽象方法
-
也可以定义 静态的(static)、默认的方法(default)
-
格式 : interface 接口名{ }
这里指出了抽象方法,我们来介绍一下抽象方法
五、抽象方法
举个买车票的例子:
买车票: 从深圳到北京是一个抽象行为,具体实现从深圳到北京方式以及路线是可以变化的
-
起始站 目的站
-
A C
- 火车票
- A -> Z -> C
- A -> R -> F -> C
- A -> F -> V -> C
-
抽象行为定义为接口
-
每种具体的实现方式 作为接口的实现类
-
1:创建一个类实现接口 implements
-
2: 重写接口中的抽象方法 为实体方法
定义接口深圳去北京SZToBJ
public interface SZToBJ {
void fromSZtoBeiJing();
}
另建一个用户类,里面存放着要调用的接口方法,要调用接口的方法,自然函数的要传入一个接口,自然这个接口我们之后会自动使用接口的实现类,发生向上转型
public class User {
// 由接口作为参数类型 定义一个参数
public void goBeijing(SZToBJ tobj){
// 接口变量名调用接口的抽象方法
tobj.fromSZtoBeiJing ();
}
}
定义实现接口的类,我这里使用了01,02,03来区分三种实现方式
public class SZToBJ_01 implements SZToBJ{
// 重写方法
@Override
public void fromSZtoBeiJing(){
System.out.println ("深圳出发");
System.out.println ("经停拉萨");
System.out.println ("到达北京");
System.out.println ("费用:2000");
}
}
class SZToBJ_02 implements SZToBJ{
// 重写方法
@Override
public void fromSZtoBeiJing(){
System.out.println ("深圳出发");
System.out.println ("经停重庆");
System.out.println ("到达北京");
System.out.println ("费用:1500");
}
}
class SZToBJ_03 implements SZToBJ{
// 重写方法
@Override
public void fromSZtoBeiJing(){
System.out.println ("深圳出发");
System.out.println ("经停上海");
System.out.println ("经停杭州");
System.out.println ("到达北京");
System.out.println ("费用:2500");
}
}
到最后一步啦!我们要调用不同情况,这个Main类定义在哪里都可以运行的
class Main{
public static void main(String[] args){
// 基于接口 实现了三种方式的实现类
SZToBJ_01 tb01=new SZToBJ_01 ();
SZToBJ_02 tb02=new SZToBJ_02 ();
SZToBJ_03 tb03=new SZToBJ_03 ();
// 用户选择其中一种
User user1 = new User();
user1.goBeijing (tb02);
user1.goBeijing (tb01);
}
}
六、接口能够创建对象吗(匿名内部类)
可能小伙伴看了半天,感觉接口和类也没什么大的差别,类能创建对象,那么借口能不能用同样的方式创建对象呢?
我们尝试一下
经过idea自动改错后,我们发现它变成了这个样子:
好熟悉!这不就是实现接口中的方法嘛。因此我们这样并不是创建了一个接口对象,而是创建了一个类s来实现接口,这种方式叫做“匿名内部类”,就是创建了一个只可以使用一次的类,创建匿名内部类的目的就是为了简化接口使用,不然我们又要创建子类实现接口方法,然后这个子类又要创建对象。
七、另一实例,开锁
创建锁接口
/**
* 抽象锁接口
* - 自己创建一个类,实现接口,从而实现一把具体的锁
* - Lock 具有对于 开 关 行为的分类 功能
* - 所有的实现了Lock的实际锁 都是Lock 接口的子类
*/
public interface Lock{
void lock();
void unlock();
}
实现多种解锁方法
public class FaceIDLock implements Lock{
@Override
public void unlock(){
System.out.println ("人脸识别正确,解锁 开门 ");
}
@Override
public void lock(){
System.out.println ("人脸识别正确,上锁 关门");
}
}
class KeyLock implements Lock{
@Override
public void unlock(){
System.out.println ("Key 验证正确,解锁开门!");
}
@Override
public void lock(){
System.out.println ("Key 验证正确,上锁 关门 ");
}
}
实现
public class Door{
Lock lock; // 接口声明对象变量名
public void open(){
lock.unlock ();
}
public void close(){
lock.lock ();
}
}
class DoorManage{
public static void main(String[] args){
Door door1 = new Door ();
// 先给 lock 初始一个具体的锁对象
// 创建了Lock 接口的子类对象
FaceIDLock faceIDLock = new FaceIDLock ();
// 装锁
door1.lock = faceIDLock;
door1.open ();
door1.close ();
KeyLock keylock = new KeyLock ();
door1.lock=keylock;
door1.open ();
door1.close ();
}
}
//先给 lock 初始一个具体的锁对象
// 创建了Lock 接口的子类对象
FaceIDLock faceIDLock = new FaceIDLock ();
// 装锁
door1.lock = faceIDLock;
door1.open ();
door1.close ();
KeyLock keylock = new KeyLock ();
door1.lock=keylock;
door1.open ();
door1.close ();
}
}