抽象类和接口
用关键字abstract修饰的类称为抽象类。例如:
abstract class A {
…
}
用关键字abstract修饰的方法称为抽象方法。对于抽象方法,只允许声明,不允许实现,即抽象方法只有方法声明,而没有方法体。例如:
abstract int min(int x,int y);
-
抽象类可以包含抽象方法。
抽象类可以包含普通类能够包含的任何东西,例如非抽象方法、成员变量等,此外还可以有抽象方法。例如:
abstract class A { abstract int min(int x, int y); // 抽象方法 int max(int x, int y) { // 非抽象方法,即普通方法 return x>y?x:y; } }
-
抽象类也可以没有抽象方法
包含抽象方法的类一定是抽象类(必须用abstract修饰),即只有抽象类才能具有抽象方法;
不能在非抽象类中声明抽象方法。 -
抽象类不能用new运算符创建对象,即抽象类不能直接实例化。
-
抽象类不能使用final修饰,抽象方法也不能使用final修饰。
-
抽象类的作用:可以使程序的设计者把主要精力放在程序的设计上,而不必拘泥于细节的实现上。
abstract class A {
abstract int sum(int x,int y); // 抽象方法
int sub(int x,int y) { // 非抽象方法
return x-y;
}
}
class B extends A {
int sum(int x, int y) { //子类必须重写父类的sum方法
return x+y;
}
}
public class TestExample {
public static void main(String args[]) {
B b=new B();
int sum=b.sum(30,20); //调用重写的方法
int sub=b.sub(30,20); //调用继承的方法
System.out.println("sum="+sum);
System.out.println("sum="+sub);
}
}
可以通过上转型对象调用非抽象子类按不同方式重写的方法,从而可实现不同的行为或功能(多态)。
利用多态设计程序的好处:可以体现程序设计的“开-闭”原则。
如果一个类定义时全部由抽象方法和全局常量组成,那么这种类就称为接口。
抽象方法只有方法声明,而没有方法体,即没有实现细节。抽象方法使用abstract修饰;
全局变量,默认使用static和final修饰,又称为接口中的域。
使用关键字interface(而不是class)定义一个接口。
接口使抽象的概念更深入了一层,可将其想象为一个“纯”抽象类。
-
不能对接口直接进行对象的实例化操作;
-
接口中只有全局常量,没有成员变量,所以接口中不能有构造方法;
-
接口的实现类使用implements关键字实现接口;
-
接口的实现类(如果不是抽象类)必须重写接口中所定义的全部抽象方法;
-
一个接口可以继承扩展多个父接口;
-
一个类可以实现多个接口。
-
利用接口的子类,采用对象的向上转型方式,进行接口对象的实例化操作。
interface Printable{ public static final int MAX = 100; //等价写法:int MAX = 100; public abstract void add(); //等价写法: void add(); public abstract float sum(float x, float y); }
接口支持多继承
interface 接口名 extends 接口1, 接口2,…… {
…
}
一个类通过使用关键字implements声明自己实现一个或多个接口。 如果实现多个接口,则用逗号将接口名隔开。语法格式:
class 类名 implements 接口1,接口2,……{
…
}
在重写接口方法时不仅要去掉abstract修饰符,给出方法体;而且方法的访问权限一定要明显地使用public来修饰,否则会降低访问权限(不允许)。
一个类可以在继承某个类(只能一个,而且可以是抽象类)的同时实现一个或多个接口。例如:
Class Dog extends Animal implements Eatable, Sleepable{
…
} //Dog类在继承父类Animal的同时实现Eatable和Sleepable两个接口
需要注意以下几点:
- 类重写的接口方法以及接口中的常量可以被类的对象调用,而且常量也可以用类名或接口名直接调用;
- 声明接口时,如果在关键字interface前面加上public关键字,就称这样的接口是一个public接口,它可以被任何一个类声明实现;否则,如果没有加上public,它只能被与该接口在同一个包中的类声明实现;
- 如果父类实现了某个接口,那么其子类也就自然实现了该接口;
- 接口也可以被继承(仍通过关键字extends声明),子接口将继承父接口中的所有方法和常量。
- 如果一个类声明实现某个接口,但没有重写接口中的所有方法,则该类必须是抽象类。
接口回调
1.接口回调,是指把实现某一接口的类创建的对象的引用赋给该接口声明的接口变量中,那么该接口变量就可以调用被类重写的接口方法;
2.接口与多态
由接口产生的多态就是不同的类在实现同一个接口时可能具有不同的实现方式,那么接口变量在回调接口方法时就可能具有多种形态。
接口与抽象类的异同
共同点:
- 都有抽象的行为,约束了它们的实现者(类)或者子类必须实现的业务功能。
- 接口中的所有行为都是抽象行为;
- 抽象类通常都有抽象行为。
不同点:
- 抽象类与其子类从大的范畴来讲它们属于同一类型(或同一种事物),抽象行为也决定了它的所有子类应该具有的行为。因此,抽象类是对属于同一种类型的不同事物的共同行为的一种抽象或表达;
- 接口中的抽象行为可以被任何类实现,实现这个接口的类可以是不同的类(这些类之间毫无关系)。因此,接口是对不同种类型的事物的共同行为的一种抽象。