为了提高代码的复用性,可以将一类事物中具有的共同属性和行为抽取出来,这一类事物中又可以细分成不同类别的事物(子类),不同的子类行为实现可能各不相同,某些行为是大家共有的,我们对实现方式各异的行为进行抽象时就不能具体指明行为的实现。为了达到抽象的目的,我们可以使用抽象类来表示这一类事物。
接口实际上就是一个抽象类,但接口只关心功能,并部关心功能的具体实现。所以接口中的方法只有声明而没有任何实现。Java不支持多继承,但使用接口就可以间接实现多继承。
1.理解抽象类和接口的作用
2.熟悉抽象类与具体类,接口的区别
3.掌握抽象类和抽象方法的定义、抽象类的使用和引用
4.掌握接口的继承并使用接口间接实现类的多重继承
5.理解接口的定义、使用以及引用
那么抽象类具体该如何使用呢?它存在的意义是什么?为了解决这个问题,首先我们创建两个类分别为猫、狗
class Dog{ private String color; public void speak() { System.out.println("汪汪! "); } } class Cat{ private String color; public void speak() { System.out.println("喵喵! "); } }
从上诉两个类的定义中,可以看到,Cat类和Dog类具有相同的属性color以及方法speak,为了减少代码重复性我们可以抽象出一个animal类,然后让Dog和Cat来继承它,我们可以看到由于不同的动物叫声是不同的,在写超类的animal时我们并不能确定具体speak的实现,于是我们就可以用抽象类,抽象类允许只定义方法,而不实现方法,由继承的子类来实现具体方法。
抽象类 | 具体类 | |
---|---|---|
作用 | 定义一类事物的一般特性 | 用于表示客观世界的对象 |
特点 | 不能实例化 | 可以实例化 |
可以定义抽象办法 | 定义的方法一定要实现 | |
可以提供也可以不提供继承的抽象方法实现 | 必须提供所有方法的实现 |
抽象类是不能实例化的类,定义时需要使用关键词abstract 修饰符声明,定义的一般格式如下
[访问修饰符]<abstract>class <类名> {[成员变量声明] [方法定义] } 例如 public abstract class Figure { 类体 }
抽象类主要用来表示一类事物具有的共同功能,如果某类下的各个子类的功能实现方法完全相同,应在抽象类中给出方法的具体实现,如果该类下的各个子类的功能实现方式不完全相同,只能声明方法,而不能实现方法。由此可见抽象类中可以包含抽象方法,也可以包含具体方法。
抽象类不能实例化,抽象类中定义的方法可以包含抽象方法,也可以不包含抽象方法,对于抽象方法的实现必须通过抽象类的子类来实现。所以对于抽象类使用的问题主要就是对它的继承以及对其中方法的重写。需要注意的时,继承抽象类的子类必须全部实现抽象类所定义的抽象方法,否则该子类必须声明为抽象类。
abstract class A{ abstract void f(); abstract void g(); } abstract class Y extend A { void f(){ ...} } class B extend A{ void f(){... } void g(){ ....} }
虽然我们不能实例化抽象类,但可以像具体类一样,创建抽象类引用。不同于具体类的是,抽象类引用来自继承它的子类的实例,即抽象类引用是一个抽象类子类对象的向上转型对象,通过这个抽象类型的向上转型对象,同样可以实现对象的多态性。使用抽象类型向上转型对象在运行时需要调用子类对象中继承或重写的方法。
接口的实质是一个抽象类,但与抽象类不同的是接口中只能包含常量的定义和方法声明。接口只关心功能,并不关心功能的具体实现。所以在接口中的方法只有声明,没有实现。
[访问修饰符]interface<接口名>{ [常量定义列表] 返回类型 方法名1(参数列表); 返回类型 方法名2(参数列表); } 例如: interface Get( int getNum(); } public class Test implements Get{ int num=0; public int getNum{ return num; } }
如果希望所有实现了接口德尔类都可以访问同一个常量,则可以在接口中声明常量。在接口中声明的常量默认是公共的、静态和最终的 ,所以在声明变量时一般不需要再次声明,声明接口常量的同时必须对常量进行赋值,常量一旦赋值后就永远不能改变.。
interface Print { int OP=1; void print() } public class Test implenments Print{ public void print(){ System.out.println(OP); } }
通过使用接口可以间接实现类的多种继承,一个类通过使用关键字implements在声明语句时声明自己使用一个或多个接口。使用多个接口时,各个接口之间要用逗号隔开。使用格式如下
[访问修饰符][类型修饰符]class 类名 implement 接口名1,接口名2.... class Fish extend Animal implements Speak,Sleep { }