Java基础
1.interface
引用数据类型:类、数组、接口
1.1 概述
接口是除了类和数组之外,另外一种引用数据类型
接口和类不同,类的内部封装了成员变量、构造方法和成员方法,而接口的内部主要就是封装了方法和静态常量。
接口的定义和类很类似,但是接口需要使用 interface
关键字来定义
接口最终也会被编译成.class文件,但一定要明确接口并不是类,而是另外一种引用数据类型
例如,
//使用interface关键字来定义接口
public interface Action {
//接口中的静态常量
public static final String OPS_MODE = "auto";
//接口中的抽象方法
public void start();
//接口的抽象方法
public void stop();
}
注意1, 定义类使用关键字class
,定义接口使用关键字interface
注意2,接口中的属性都是公共的静态常量
注意:常量的名字一般需要全大写
注意3,接口中的方法都是抽象方法
注意:JDK8中,还允许在接口中编写静态方法和默认方法
注意:JDK9中,还允许在接口中编写私有方法
注意4,接口的中抽象方法,不需要使用abstract
修饰符,因为接口中的方法默认就是抽象方法
在接口中,可把一些修饰符省去不写:
//使用interface关键字来定义接口
public interface Action {
//接口中的静态常量
String OPS_MODE = "auto";
//接口中的抽象方法
void start();
//接口的抽象方法
void stop();
}
接口里面的属性,默认就是public static final修饰的
接口里面的方法,默认就是public abstract修饰的
所以这些都可以省去不写的
含有静态方法和默认方法的接口:(JDK8)
public interface Action {
public default void run1() {
// 执行语句
}
public static void run2() {
// 执行语句
}
}
含有私有方法的接口:(JDK9)
public interface Action {
private void run() {
// 执行语句
}
}
注意,我们一般所使用的接口,大多数都只是含义抽象方法
1.2 接口实现
类和类之间的关系是继承,类和接口之间的关系是实现:一个类实现了一个或多个接口
接口和类不同,类可以实例化创建对象,而接口不能创建对象,只能让其他类来实现。
一个类实现了一个接口,那么该类可以称为这个接口的实现类。类实现一个接口 和 类继承一个父类 的效果类似,格式相仿,只是关键字不同,实现使用 implements 关键字,而继承使用的是extends关键字。
一个类实现了接口,那么就要实现接口中所有的抽象方法,否则这个类自己就必须声明为抽象类。
例如,实现一个接口
public interface Action {
void run();
void sayHello();
}
//类实现接口,没有实现接口中的抽象方法,那么这个类就必须声明为抽象类
abstract class Student implements Action{
}
public interface Action {
void run();
void sayHello();
}
//类实现接口,并且实现了接口中所有的抽象方法
class Student implements Action{
public void run(){
//...
}
public void sayHello(){
//...
}
}
例如,实现多个接口
public interface Action {
void run();
void sayHello();
}
public interface Mark{
void star();
}
//类实现接口,并且实现了接口中所有的抽象方法
class Student implements Action, Mark{
public void run(){
//...
}
public void sayHello(){
//...
}
public void star(){
//...
}
}
一个类实现了多个接口,那么就需要把这多个接口中的抽象想法全都实现
JavaAPI中的String
类,也实现了多个接口:
可以看出,String类继承Object类的同时,又实现了三个接口
1.3 接口继承
java中,类和类之间是单继承,接口和接口之间是多继承
例如,
//实现该接口的类,将具有run的功能
public interface Runable {
void run();
}
//实现该接口的类,将具有fly的功能
interface Flyable{
void fly();
}
//实现该接口的类,将具有run的功能,fly的功能,以及Action接口独有的doSomething功能
interface Action extends Runable,Flyable{
void doSomething();
}
//实现类,实现Action接口,就必须要实现Action及其父接口中的所有抽象方法
class Demo implements Action{
@Override
public void run() {
}
@Override
public void fly() {
}
@Override
public void doSomething() {
}
}
1.4 多态
多态的前提是继承,必须要先有子父类关系才行,而类和接口之间的实现关系,其实也是继承的一种形式,所以在类和接口的实现关系中,也可以使用多态
接口的引用执行它的实现类对象:
public interface Action {
void run();
}
class Student implements Action{
@Override
public void run() {
}
}
class Teacher implements Action{
@Override
public void run() {
}
}
class StudentTest{
public static void main(String[] args) {
//声明接口的引用
Action a;
//可以指向它任意一个实现类对象
a = new Student();
a = new Teacher();
}
}
接口的引用调用方法,调用到的是实现类中重写的方法
class StudentTest{
public static void main(String[] args) {
Action a = new Student();;
//调用是到的方法是Student中重写(实现)的方法
a.run();
}
}
注意,抽象方法的实现,也算是一种方法的重写,形式、语法完全一致。
1.5 案例
public interface Action {
void run();
}
interface Mark{
void star();
}
class Student implements Action,Mark{
@Override
public void run() {
System.out.println("student run...");
}
@Override
public void star() {
System.out.println("student star...");
}
}
思考,下面代码是否正确?:
class StudentTest{
public static void main(String[] args) {
Action a = new Student();
a.run();
a.star();
}
}
mian方法中,a.run()
编译运行都是正确的,但是 a.star()
方法的调用是编译错误的。
因为,在编译的时候,编译器会先检查引用a
所属的类型(Action
)中,是否存在当前要调用的方法(star
),如果没有那么就直接编译报错。
那么在这种情况下,该如何修改代码,才能正确调用到star
方法?
class StudentTest{
public static void main(String[] args) {
Action a = new Student();
a.run();
Mark m = (Mark)a;
m.star()