抽象类
- 强制子类重写其定义的抽象方法。
- 抽象类中可以不定义抽象方法,这样做仅仅是不让该类建立对象。
抽象类的注意事项
抽象类和抽象方法都必须用abstract修饰,抽象方法必须存放在抽象类中。
abstract不能与private,static,final共用修饰函数。
抽象方法不存在方法体,通过 new 对象调用方法,没意义。
抽象类中的方法要被调用,必须由子类重写其所有的抽象方法后,建立子类对象调用,如果子类只重写了部分抽象方法,那么该子类还是一个抽象类。
抽象类只是比一般类多了抽象方法,不存在抽象属性
public static void main(String[] args) {
new DemoImpl().getCount();
}
//抽象类
abstract class IDemo{
public String mStr = "DemoString";
//抽象方法,将不确定的部分交给实现类去实现
abstract int addCount();
public void getCount(){
System.out.println(addCount());
}
}
//实现类
class DemoImpl extends IDemo{
@Override
int addCount() {
return 1;
}
}
接口
接口的注意事项
接口是一个特殊的抽象类,不能创建对象,原因和抽象类相同。
接口没有构造方法,成员变量都是常量,默认的修饰符为public static final,方法都是抽象方法,默认的修饰符为public abstract。
非抽象类实现一个接口时,必须要把接口中所有的方法全部实现,抽象类实现一个接口时,可以实现也可以不实现接口中的方法。
一个类可以实现多个接口,不同接口用 , 分隔。
class 类名 implements 接口类A,接口类B{
public void 接口实现方法名();
}
- 接口与接口之间可以多继承。
public interface 接口类名 extends 接口A,接口B{
}
接口的作用
1.定义约束规范
假设为手机的功能定义类,大部分手机功能都相似,在写代码时,如果不用接口统一定义这些功能,难免陷入粘贴复制的局面。
定义规范
public interface IFirstPhone {
void call();
void sms();
}
具体实现
public class PhoneImpl implements IFirstPhone {
@Override
public void call() {
printf("call");
}
@Override
public void sms() {
printf("sms");
}
public void printf(String message) {
System.out.println(message);
}
}
2.功能拓展
接口可以多继承,多实现,如果有了新产品功能添加可以多定义一个接口。
public interface ISecondPhone extends IFirstPhone{
void netConnection();
void photo();
}
public class PhoneImpl implements IFirstPhone ,ISecondPhone{
@Override
public void call() {
printf("call");
}
@Override
public void sms() {
printf("sms");
}
@Override
public void netConnection() {
printf("netConnection");
}
@Override
public void photo() {
printf("photo");
}
public void printf(String message) {
System.out.println(message);
}
}
3.程序解耦
是对于多态的利用,一个类实现了接口后,这个接口即可以作为这个类的父类引用,隐藏内部实现。
public class Main {
public static void main(String[] args){
ISecondPhone secondPhone = new PhoneImpl();
secondPhone.call();
secondPhone.sms();
secondPhone.netConnection();
secondPhone.photo();
}
}
接口补充
JDK1.8前,当一个类实现接口时,必须重写接口中所有的方法,否则这个类将会成为一个抽象类。
但是在实际开发中,接口中有些方法不需要重写,针对这个问题,1.8后提供了接口的默认方法。
public interface IFirstPhone {
void call();
void sms();
default void cell() {
System.out.println("不需要强制重写");
}
}
public class PhoneImpl implements IFirstPhone {
@Override
public void call() {
}
@Override
public void sms() {
}
}
可以根据实际决定默认方法是否需要重写
public class PhoneImpl implements IFirstPhone {
@Override
public void call() {
}
@Override
public void sms() {
}
@Override
public void cell() {
}
}
接口中也提供了相应的静态方法
public interface IFirstPhone {
void call();
void sms();
default void cell() {
System.out.println("不需要强制重写");
}
static void demo(){
System.out.println("只能通过接口名调用");
}
}
public class Main {
public static void main(String[] args){
IFirstPhone firstPhone = new PhoneImpl();
firstPhone.cell();
firstPhone.sms();
IFirstPhone.demo();//静态只能通过接口名调用,不能通过引用
}
}