1、抽象方法
在介绍抽象类和抽象方法之前,需要先了解一下抽象方法, 抽象类, 接口的基本概念。抽象方法就是一个方法,其比普通方法多了一个关键字abstract修饰,少了方法体。抽象类就是一个类,其比普通类多了一个关键字abstract修饰。接口就是用关键字interface修饰,其是一种规范要求实现者必须遵守其所有定义的规范。
为什么会出现抽象方法了?相比较于普通方法,抽象方法少了方法体,多了一个abstract关键修饰(也可以把抽象方法看出是一个函数的声明)。
接下来举一个例子:
比如对于一个Graph类, 其中有一个计算面积的方法getArea()
,由于不同的图形其计算面积的具体实现不同,所以在继承的时候会根据自己是什么图形进行重写getArea()
方法。
这样一看图形类Graph的getArea
方法并没有什么问题,但是啦代码可以更好因为其实我们觉得它的return 0.0
这个方法体是冗余的,我们只需要告诉其子类,父类有一个计算面积的方法叫做getArea()
即可,(这里就引入了抽象方法出来,其实我们只需要对该方法进行声明就可以啦,具体怎么实现交由其子类去完成)。这样还有一个优点就是子类继承额时候必须要实现该方法,否者会出现编译错误。
其代码如下:
抽象方法有以下三个特点:
-
抽象方法是没有方法体的:因为其具体的实现是交由其子类去实现
-
抽象方法必须要定义在抽象类或者接口当中:如果一个类中有一个抽象方法,即使该类没有被abstract修饰,其也是一个抽象类
-
抽象方法是不能被private, final, static修饰的
4个访问修饰符的权限范围大小:
访问修饰符 | public | protected | default | private |
---|---|---|---|---|
父类本身 | √ | √ | √ | √ |
同包 | √ | √ | √ | |
子类(可能不是同包) | √ | √ | ||
其它包 | √ |
由上述可知抽象方法就是需要子类去实现的 所以不能是private,因为继承不会继承父类的private修饰的方法和属性;同理final修饰的类不能被继承故也不可以;对于static修饰的方法是在类加载的时候就已经确定了其具体方法细节,但是abstract修饰的方法是没有方法体,其具体形式是子类实现的,所以不能使用static。
2、抽象类
概念:abstract修饰的类,就成为了抽象类,抽象类要有子类才有意义(因为抽象类不能直接创建对象,得通过子类继承间接创建父类(即抽象类)对象)
抽象类的注意点:
- 抽象类是不能直接被创建对象的
- 抽象类当中可以有抽象方法也可以有普通方法
- 子类如果继承抽象类但是却没有去覆盖所有的抽象方法,会编译爆红,所以要么全部实现父类的抽象方法,要么把子类也变成一个抽象类
- 抽象类的构造方法不能定义为私有化(子类继承抽象类的时候,会去调用父类的构造方法 如果设置为private则子类不能调用,代码就出现编译错误)
- 抽象类不能使用final来修饰, final修饰的类不能被继承,但是抽象类就是需要继承故而不能使用final
3、接口
概念:接口表示一种规范,使用抽象方法来去定义一组功能,必须要实现者给提供方法的实现
接口的注意点:
-
接口当中定义的方法 都是public abstract xxx的公共抽象方法
-
接口是可以继承接口的,是可多继承的;但是类只能单继承,可以多实现
类可以看做是对事物的抽象,即表示这个对象是什么,所以说不能多继承,比如有person类和animal类,某个类只能继承一个,即某个类只能是狗或人不能即是狗又是人;接口是对事物属性的抽象,比如狗可以吃饭,人也可以吃饭,狗可以叫人也可以叫,抽象出两个接口eat和shout,即某个类可以实现eat接口和shout接口,接口多继承就相当于把每个单独功能的接口的所有的抽象方法合并在一起,成为一个功能丰富的接口 -
接口当中定义的变量都是全局的静态常量 public static final
-
接口是没有构造器,接口是不能构造对象的
4、接口和抽象类的异同
相同:
- 自己都不能进行实例化
- 都可以定义抽象方法,抽象方法子类去实现
区别:
- 抽象类可以包含普通方法和抽象方法,接口只能有抽象方法不能有普通方法
- 抽象类可以有普通变量,而接口当中的变量都是默认为常量 public static final
- 接口是没有构造器,而抽象类是有构造器的
构造器的目的就是为了创建对象:初始化成员变量和调用方法;在接口里面成员变量全是public static final 都是常量类加载就初始化好了,所以没必要进行初始化,还有就是调用方法因为接口里面只能有抽象方法不能有其他的普通方法,所以也没有必要进行调用,对于抽象方法的调用交给子类就行,所以说接口没必要有构造函数。那么抽象类需要构造函数的原因——抽象类里面可以有普通方法,这个普通方法是需要被调用的,以及抽象类还有成员变量也需要进行初始化,所以需要构造器