抽象类和接口的详说:
在上面一篇博客中的介绍以后,下面整理的是面向对象中剩下的一些特征:抽象类还有接口。
其实如果简单的说,可以这样理解,接口是完全的抽象类。
下面先说道说道这个抽象类:
- 在抽象类中可以有实现的普通方法,当然有抽象方法。甚至,抽象类中还可以没有抽象方法,但是抽象方法要么在抽象类中要么在接口中,绝对不能放在普通的class类中。
- 抽象类中,可以写一个构造器,当然也可以写一个代码初始化块,这在接口中是绝对不存在的。
- 上面所说的,抽象类中也是可以写带有方法体的方法的普通方法。
其次整理了一些关于接口的相关规则:
- 首先,接口中必须全部是抽象方法,而不能有一个带有方法体的具体实现的方法,这和抽象类中是有很大的不同的。
- 因为接口的特殊性,接口是不能创建实例的,因此,其不可能有一个实例变量的;
- 接口中,只能有四种”包含物“:①:类成员变量(没有实例变量);
②:接口全部都是抽象方法;
③:接口中可以有类方法;
④:接口中可以有默认方法;
下面整理一下上面接口中所说的,四种“包含物”中的相关规则:
①:首先是类成员变量:其修饰符是:public static final来修饰一个变量的。所以,加入你在接口中定义了一个类变量这样写道:int count=5; 这其实等同于public static final int count=5; 所以说就算你不写public static final,系统会默认写上的。因为接口不能实例,所以不能有实例变量。
②:上面所说的第二点就没有什么好说的了,直接方法的修饰符就是abstract即可。
③:上面所说的接口中的类方法,定义起来也很简单,直接一个public static 即可,没有public也可以,系统会默认加上的。
④:关于接口中的默认方法:只要以default定义即可。和上面一样,不加上public也可以,系统会默认补上的。
--当然了,上面接口中的类方法和默认方法,是可以写方法体的哦!
下面首先贴上一段关于抽象类的代码:
/*
* 抽象类中是抽象方法,但是也是可以有普通方法的。
*/
public abstract class Car {
abstract String getRidus();
public String showResult(){
return "结果是:"+getRidus();
}
}
上面的是一个抽象类,这里面有一个getRidus的抽象方法,下面还有一个普通方法,返回值用到了上面抽象方法的返回值。
下面的该抽象类的实现类:
public class Java318 extends Car {
public static void main(String[] args){
Car car=new Java318();
/*
* 结果是:28
* 28
*/
System.out.println(car.showResult());
System.out.println(car.getRidus());
}
@Override
String getRidus() {
// TODO Auto-generated method stub
return "28";
}
}
注意,实现一个抽象类是直接使用extends即可。
下面贴出一个接口代码:
package Interfa;
/*
* 在接口中,所有的类成员变量都会被默认加上public static final的修饰符去修饰
*/
/*
* 接口中的普通方法一定是public abstarct修饰
* 接口中的成员变量一定是public static final来修饰的
* 接口中的默认方法都是public default来修饰的
* 接口中的类方法都是public static进行修饰的
* 接口中的普通方法,是绝对不能是static来进行修饰的
* 接口中是没有构造器也没有类的初始化块的
*/
//接口可以实现多继承,但,只能多继承接口,不能是一个具体的类
public interface CarInfo {
//接口不能有初始化块
// static{
// carCount=5;
// }
//基于上面的文字说明,所以下面这句话将会引起编译的错误,错误原因是,final修饰的该变量还没有进行初始化
// int carCount;
int carCount=4;
String getCount();
default String showResult(){
return getCount();
}
static String staticCar(){
return "车辆数:"+carCount;
}
}
下面是一个接口的实现类:
package Interfa;
public class ShiXian implements CarInfo {
public static void main(String[] args){
System.out.println("调用CarInfo中的类变量:"+carCount);
System.out.println("调用接口中的类方法:"+CarInfo.staticCar());
//接口中的默认方法,因为不是static修饰,所以不能通过类名.方法名调用,
//因为接口不能实例化,所以不能实例化调用
//因为ShiXian类实现了CarInfo的接口,所以创建对象来调用接口中的方法
System.out.println(new ShiXian().showResult());
}
@Override
public String getCount() {
// TODO Auto-generated method stub
return "showCount方法执行";
}
}
对上面接口代码的一些整理说明:
在接口中上面所说的,可以包含类方法,默认方法,抽象方法还有类变量,下面将整理介绍对于各个方法的调用:
①:类方法:类方法,是public static来创建修饰的,所以,可以直接接口名称.类方法名称就可以完成调用了。
②:默认方法:默认方法,因为是public default来修饰的,因为,其不能想类方法的调用方式去调用,而是先实例继承接口类的类实例,去调用接口中的默认方法,就像上面的new ShiXian().showResult();
③:类变量和类方法的调用方式是一样的,直接通过接口.类变量名称即可完成调用。
上面都是我们自己写的接口或者是抽象类,我们平时写代码中,也会时不时的用到API中的接口,其中一个接口就是Runnable了(线程实现的方法之一),下面贴上一个代码来体验一下API中接口:
package XianCheng;
public class MyThread implements Runnable{
public static void main(String[] args){
Thread t1=new Thread(new MyThread());
t1.start();
}
@Override
public void run() {
// TODO Auto-generated method stub
for(int i=0;i<5;i++){
System.out.println(i);
}
}
}
打印一个非常简单的五个数字。 这里我们实现的就是Runnable的接口了,这个接口里,首先先实现方法Run()。然后实例一个Thread。因为该类是实现了Runnable的,将MyThread实例作为参数放入Thread中的参数中就是等于Runnable作为参数放入。因此可以实现。因为没有对Thread写上额外的一些操作,所以最后不要忘记start方法就可以了。
因此总得来说:抽象类和接口其实就是一个模版。总体来说就是作为一个模版来给继承或者实现的类来按照其中的规范来写代码。
但是,两者也是有一点区别的,接口更接近于模版,细分来说,抽象类就是完成一半功能的模版,里面还有一些东西,等着继承类来具体的”加血加肉“。而接口,就是当作模板了。
上面主要是整理了一下抽象类还有接口的思路,没有写入什么代码来去演示,所以,这里面就只有两个小一点的代码来讲究演示一下罢了。
以前还整理过一些面向对象的特征,分享URL:https://my.oschina.net/zcysxj/blog/861038