abstract和interface关键字介绍
一、abstract关键字介绍
abstract可以修饰方法、类。使用abstract修饰的方法和类分别叫做抽象方法和抽象类。
1、抽象方法
抽象方法的定义:指可以通过abstract关键字声明的方法,这种方法只有方法声明没有方法体。
抽象方法存在的意义:如果所有的子类都对父类的某个或者某些方法做了重写,那么父类中的方法保留方法体就变得没有意义,那么就可以将其定义为抽象方法。
抽象方法的特征:
- 抽象方法是为了继承时重写而存在的。
- 抽象方法不能用final修饰。原因:final方法是最终方法,子类无法重写,而抽象方法存在的目的就是为了重写。如果不让重写,就和原本意图相矛盾了。
- 抽象方法不可以用private修饰。原因:private方法是私有方法,子类中无法看到,更无法重写,没有意义。和抽象方法原本意图相矛盾。
- 抽象方法不能用static修饰。原因:静态成员属于类,静态方法无法重写,和定义抽象方法的本意相矛盾。
- 抽象方法可以重载。
具体示例如下:
class A{ } abstract class B extends A { //抽象类可以具有成员属性 private String name; //抽象类可以具有构造方法 public B(String name) { this.name = name; } //抽象方法可以重载 public abstract void ma(); public abstract void ma(String str); } abstract class C extends B { public C(String str) { super(str); } //抽象方法可以重载 public abstract void m1(); public abstract void m1(String str); //抽象方法可以被final,static,private修饰吗 //不可以,因为这几个都不能被重写或者继承 /*public abstract final void m2(); public abstract private void m2(); public abstract static void m2();*/ } //final与abstract不能同时声明一个类, //抽象类存在的意义就是为了被继承,设置为final与本意违背 //final abstract class D {}
2、抽象类
定义:一个类一旦被abstract修饰,就成为了一个抽象类。
抽象类的特征:
- 抽象类可以包含抽象方法。
- 抽象类无法new对象,即无法实例化。
- 抽象类主要是为了被继承而存在的。
- 非抽象类继承抽象类之后,必须实现父类中声明的所有抽象方法。
- 抽象类不能被final修饰。原因:抽象类存在的目的是为了继承,而最终类不可以被继承。
抽象类和其他类的共同点:
- 抽象类可以继承其他类,既可以继承抽象类,也可以继承非抽象类。
- 抽象类可以实现接口。
- 抽象类可以不包含抽象方法。
- 抽象类可以具有构造函数、成员属性、成员方法和静态方法。
二、interface关键字
1、接口存在的意义
由于java只支持单继承,缺少了一定的灵活性。为了弥补这一缺点。sun公司除了限定单继承之外,额外提供了接口的概念,虽然一个类只能继承一个父类,但是可以实现多个接口,从而弥补了java程序的灵活性。
2、接口的定义和使用
a、接口的定义
接口使用interface关键字来声明,接口中声明的所有方法都是抽象方法。
接口的特征:
- 接口中声明的方法必须是public abstract的,而不写默认就是public abstract。
- 接口中声明的属性必须是public static final的,而不写默认就是public static final。
- 接口中无法声明构造方法,接口也无法创建对象。
- 接口可以继承接口,且可以多继承。
- 在JDK1.8之前,接口中所有的方法都是抽象方法;JDK1.8之后,接口中的方法可以出现实体方法。相当于Java实现了多继承。
b、使用接口时注意事项
- 可以通过implements关键字使一个类实现接口。如果要同时实现多个接口,可以将过个接口通过逗号分隔依次声明。
- 一个类可以同时继承类并实现接口,其中extends关键字要出现在implements关键字之前。
- 一个普通类一旦实现了接口,则需要实现接口中的所有方法。
示例如下
/** * 接口声明的方法:1、必须是public abstract 的,而不写默认就是该种形式 * 2、接口中的属性必须是public static final 的,不写就是默认 * 3、接口中不能有构造方法,也无法创建对象 * @author Administrator * */ interface intf01 { //接口中的属性必须是public static final 的,不写就是默认 String name = "intf01"; void m01(); void m02(); } interface intf02 { String str = "intf02"; void m03(); void m04(); } //接口可以多继承 interface intf03 extends intf02, intf01 { void m05(); } class A { } //接口不能继承任何类,抽象类也不行,因为可能包含非抽象方法 //interface intf04 extends A {} //类可以既继承类又实现多个接口,extends在implements前 abstract class Person extends A implements intf01,intf02 { @Override public void m03() { // TODO Auto-generated method stub } @Override public void m04() { // TODO Auto-generated method stub } //抽象类实现接口,则可以不重写抽象方法; //普通方法必须全部实现接口方法 }
三、抽象类和接口的比较
抽象类只能单继承,接口可以多继承;
抽象类可以包含抽象方法和非抽象方法,接口所有方法方法都是抽象方法(JDK1.8之前);
抽象类和接口都可以实现多态。
真正开发时,抽象类主要用来满足继承结构树,而接口主要用来混入特性。
abstract class Person1 { public void eat() { System.out.println("吃..."); } public abstract void say(); } interface CodeSkill { public void code(); } interface DriveSkill { public void drive(); } interface CookSkill { public void cook(); } class Student extends Person1 implements CodeSkill, CookSkill, DriveSkill { @Override public void code() { System.out.println("写代码..."); } @Override public void say() { System.out.println("学生在叽叽喳喳的说..."); } @Override public void cook() { System.out.println("做饭..."); } @Override public void drive() { System.out.println("开车..."); } } public class Demo02 { public static void main(String[] args) { //抽象类和接口都可以实现多态 :即抽象类和接口都可以实例化一个继承 //他们的一个类的对象;但是只能访问到抽象类或者接口内的方法 Person1 p = new Student(); //多态 p.eat(); p.say(); //p.drive(); CookSkill cooker = new Student(); //多态 cooker.cook(); } }