一.抽象类
1.抽象方法
•解决办法:通过abstract关键字将getArea方法修饰为抽象的,此时的方法称为抽象方法。
•抽象方法是出现在基类中的一种方法,但要求在派生类中被重写。
•一个抽象方法只有方法头,没有方法主体。
访问修饰符 abstract 返回类型 方法名(参数列表);
•注意,关键字 abstract 出现在方法头中,方法头以分号结尾。
public abstract void getArea();
•包含抽象方法的类就会自动变成抽象类,因此必须以abstract关键字声明。
•如果派生类没有重写抽象方法,编译器会报错。
•抽象方法被用来确保派生类会实现这个方法。
•实例:
–Geometry.java, Circle.java, Rectangle.java
GeometryObjectDemo.java
2.抽象类
•若类含有抽象方法,则类必须以abstract关键字声明为抽象类。
public abstract class 类名
•抽象类可以含零至多个普通方法,也可以含零至多个抽象方法。
•不论抽象类是否含抽象方法,其都不允许实例化,即不能创建抽象类的对象,因为其描述的是抽象概念。它只能作为其他类的基类。
•若父类是抽象类,且子类不想成为抽象类,则子类必须将父类中的所有抽象方法重写为带方法体的普通方法,否则子类仍必须是抽象类。
二.接口
1.概念
•接口定义的通用格式:
public interface 接口名称
{
(方法头...)
}
•接口中的所有方法都是public,抽象方法。
•一个类可以实现一个或者多个接口
•接口和所有方法都是抽象方法的抽象类非常类似。
–它不能被实例化, 而且
–在接口中所列的所有方法必须在别处被重写。
•接口的目的是为了给其他类提供行为说明。
•一个接口看起来就像一个类,除了:
–关键字interface 替换了关键字 class, 以及
–接口中的方法只有方法头加分号结尾,没有方法主体。
2.属性
•一个接口可以有属性:
–在接口中的所有属性都为 public、final 和 static.
•因为他们会自动地变为 final, 所以你必须为它们提供初始化值。
public interface Doable
{
int FIELD1 = 1, FIELD2 = 2;
(Method headers...)
}
•在这个接口中, FIELD1 和 FIELD2 是 public final static int 变量。
•任何实现这个接口的类都可以访问这些变量。
3.实现
•如果一个类要实现接口,它需要在类头中使用implements 关键字。
public class RubberDuck extends Duck implements Quackable
4.实现多个接口
•一个类只能从一个基类派生。
•Java 允许一个类实现多个接口。
•当一个类实现多个接口,它必须实现所有接口中的方法。
•为了在类定义中说明实现多个接口,需要写上关键字implements,并列出接口的名字,接口名之间用逗号分隔。
public class MyClass implements Interface1,
Interface2,
Interface3
5.继承接口
•与类的继承类似,接口之间也可以继承。
•接口只能继承接口,而不能继承类。
•与类的继承类似,接口的继承也表达了“is-a”的逻辑。
•与类只能继承一个父类不同,接口可以继承多个父接口,彼此以逗号隔开(各父接口的顺序可任意),表达的逻辑是子接口既是一种父接口1,也是一种父接口2,… 。
三.抽象类与接口的比较
1. 从概念层面
接口是对动作的抽象,抽象类是对本质的抽象。
抽象类表示的是,这个对象是什么。接口表示的是,这个对象能做什么。比如,男人和女人,他们的抽象类是人类,而猫和狗的抽象类是宠物类。人类可以吃东西,宠物类也可以吃东西,但是两者不能混为一谈,因为有本质的区别。这个“吃东西”是一个动作,你可以把“吃东西”定义成一个接口,然后让两个类去实现它的方法。
所以,在高级语言上,一个类只能继承一个类或抽象类,正如人不可能同时是动物类又是植物类,但是可以实现多个接口,例如,吃饭接口、呼吸接口等。
2.从语法层面
抽象类与接口是Java提供的对现实世界中的实体进行抽象的两种机制,二者具有很大的相似性,同时也具有明显的区别。
•Java允许你创建接口类型的引用变量。
•接口引用变量可以存放任何实现该接口的对象的地址, 不管类的类型。
•这是多态的另一个实例。
•Example:
–RetailItem.java
–CompactDisc.java
–DvdMovie.java
–PolymorphicInterfaceDemo.java
•在实例代码中,声明了两个 RetailItem 引用变量 item1 和 item2。
•item1 变量指向 CompactDisc 对象,item2 变量指向 DvdMovie 对象。
•当一个类实现了接口,接口的继承关系就被建立了。
–CompactDisc 对象like a RetailItem对象,
–DvdMovie 对象like a RetailItem对象。
•你不可以创建接口实例。
RetailItem item = new RetailItem(); // ERROR!
•当一个接口变量指向一个对象时:
–只有接口中声明的方法是有效的,
–当你想访问被接口引用变量所指向的对象的其他方法时,必须进行强行类型转换。
3.从使用情况层面
(1)抽象类 和 接口 都是用来抽象具体对象的,但是接口的抽象级别最高;
(2)抽象类可以有具体的方法和属性, 接口只能有抽象方法和不可变常量(final);
(3)抽象类主要用来抽象类别,接口主要用来抽象功能;
(4)抽象类中不包含任何实现,派生类必须覆盖它们。接口中所有方法都必须是未实现的;
(5)抽象类实现接口时,接口的方法在抽象类中可以被实现也可以不被实现,而普通实现接口必须实现所有接口方法。
4.从使用方向层面
当你关注一个事物的本质的时候,用抽象类;
当你关注一个操作的时候,用接口。
四.总结
抽象类的功能要远超过接口,但是,定义抽象类的代价高。因为高级语言来说(从实际设计上来说也是)每个类只能继承一个类。在这个类中,你必须继承或编写出其所有子类的所有共性。虽然接口在功能上会弱化许多,但是它只是针对一个动作的描述。而且你可以在一个类中同时实现多个接口。在设计阶段会降低难度的。