关于子类继承抽象类的问题
首先抽象类里可以有抽象方法,也可以有具体的方法。
如果子类是非抽象类,那么这个子类必须去实现父类里面所有的抽象方法(重写),而抽象类里的非抽象方法会被继承。
另外,接口中所有的方法都是抽象的,接口中可以定义数据成员,但必须是常量。如果抽象类来实现接口,不必实现接口中所有的方法,其余方法可以交给抽象类的子类实现。也就是说,一个子类继承了某抽象类,这个抽象类又实现了某接口,抽象类中若没有实现接口中所有的方法,这些没有实现的方法就由子类实现。
注:
如果接口中有default关键字修饰的方法,表示接口提供一个默认实现的方法,不强制实现类重写此方法。这种方法也可以在实现类中重写,调用的时候优先调用重写后的方法。
为什么有时候需要实现一个接口,不采用直接实现的方法,而是采用先定义一个抽象类,继承这个抽象类的方法来实现?
接口中全都是抽象的方法,而抽象类中可以有抽象方法,还可以有具体的方法,定义抽象类来实现接口中一些通用的方法,而具体的实现类,可以继承这个抽象类,拿到一些通用的方法,然后实现一些其它方法,这样做可以有效避免重复代码。
例如在我的个人秒杀项目中,Redis key前缀的设计就用到了这种方法:
package com.ghk.seckill.redis;
/**
* key前缀接口
* 接口-抽象类-实现类
*/
public interface RedisKeyPrefix {
/**
* 过期时间
* @return
*/
Integer getExpireSeconds();
String getPrefix();
}
package com.ghk.seckill.redis;
public abstract class RedisBasePrefix implements RedisKeyPrefix{
private Integer expireSeconds;
private String prefix;
/**
* 默认为过期时间为0: 永不过期
*/
public RedisBasePrefix(String prefix) {
this(0,prefix);
}
public RedisBasePrefix(Integer expireSeconds, String prefix) {
this.expireSeconds = expireSeconds;
this.prefix = prefix;
}
@Override
public Integer getExpireSeconds() {
return expireSeconds;
}
@Override
public String getPrefix() {
String simpleName = getClass().getSimpleName();
return simpleName.concat(":").concat(prefix);
}
}
package com.ghk.seckill.redis;
public class CustomerKey extends RedisBasePrefix {
private static final int TOKEN_EXPIRE_TIME= 3600;
private CustomerKey(String prefix) {
super(prefix);
}
private CustomerKey(Integer expireSeconds,String prefix) {
super(expireSeconds,prefix);
}
public static CustomerKey getByCusId = new CustomerKey("id");
public static CustomerKey getByCusName = new CustomerKey("name");
public static CustomerKey token = new CustomerKey(TOKEN_EXPIRE_TIME,"token");
}