接口 和 抽象类 的联系:
《阿里巴巴Java开发手册》有云:
- 接口类中的 方法 和 属性 不要加任何修饰符 (public也不要加)--------目的:保持代码的简洁性,并加上Javadoc注释。
-尽量不要在接口中定义变量,如果一定要定义变量,必须是与接口方法相关的,并且是整个应用的基础常量。
正例: 接口方法签名: void commit();
接口基础常量:String COMPANY = "alibaba";
接口 和 实现类 的命名有两套规则
1.【强制】 对于Service 和 DAO类,基于SOA 的理念,暴露出来的服务一定是接口,内部的实现类用 Impl 后缀与接口区别
正例: CacheServiceImpl 实现 CacheService 接口
2.【推荐】 如果是形容能力的接口名称,取对应的形容词为接口名(通常是-able的形式)
定义一个接口测试类 来观察:
// 接口测试类 public interface InterfaceTest {
// private int cnt; 报错:在接口中 ,想要定义属性,则必须 用 public static final共同修饰 // public static final int CNT ; 报错:必须赋值 static final int CNT = 10; // 通过:说明 接口中只能定义常量 abstract void show(); // 可以把 abstract关键字省略,因为接口中的方法全部是 抽象方法 void print(); // 这也是抽象方法,把abstract关键字省略了
// public void test(){
//
//} // 报错:接口中的方法全部是抽象方法,不允许存在普通方法。 当然,接口中没有构造方法
}
思考: 在现实生活中黄金 既是 金属 也是 货币,有金属的属性,也有货币的属性。而在Java中值支持单继承,怎么办?
1.定义个 IMoney 货币接口
public interface IMoney { // 货币接口 abstract void buy(); // 购买的功能 }
2.定义 IMetal 金属接口
public interface IMetal { // 金属接口 public abstract void shine(); // 会发光的功能 }
3.定义 GoldImp 黄金实现类
public class GoldImpl implements IMetal, IMoney{ // 黄金实现类 实现了 金属 和 货币 接口 @Override public void buy() { System.out.println("具备货币功能,可以购买一辆坦克....."); } @Override public void shine() { System.out.println("具备金属功能,可以发出耀眼的光芒....."); } }
测试类:
public class Test { public static void main(String[] args) { // 父类引用 指向 子类对象 形成多态 IMoney money = new GoldImpl();
money.buy(); // 编译期,调用父类中的方法。运行期,调用子类重写之后的方法 System.out.println("------------"); IMetal metal = new GoldImpl();
metal.shine(); } }
结果:
具备货币功能,可以购买一辆坦克..... ------------ 具备金属功能,可以发出耀眼的光芒.....
匿名内部类的引入
: 抽象类不能自己创建对象,接口更不能创建对象。但是若非得给接口创建对象,则需要借助匿名内部类来构造一个接口类型的对象。
匿名内部类方式:
public class Test { // 定义一个静态的方法:形参 要的是一个 IMoney的接口类型 // 接口类型的引用 作为 形参,那么实参 1.要么是 接口类型对象,2.要么是该接口实现类的对象 // 而接口没有构造方法不能够new对象,所以借助匿名内部类 public static void moneyBuy(IMoney money) { // 用钱买的功能 money.buy(); } public static void main(String[] args) { // static修饰的方法是静态方法 // 静态方法 隶属于类层级,无关对象是否创建 IMoney im= new IMoney(){ @Override public void buy() { System.out.println("我是接口的匿名内部类啊"); }}; Test.moneyBuy(im); } }
执行结果:
我是接口的匿名内部类啊
重点:A是接口类型,匿名内部类的形式
A a = new A( 方法的重写 );
若不采用匿名内部类的方法,则可以创建一个 该接口的实现类,再将该实现类作为实参传递
1.写一个 RmbImpl 人民币类
public class RmbImpl implements IMoney { // 人民币类 作 IMoney货币接口的实现类 @Override public void buy() { System.out.println("人民币当然也是货币啊"); } }
2.测试类
public class Test { public static void moneyBuy(IMoney money) { // 用钱买的功能 money.buy(); } public static void main(String[] args) { RmbImpl rmb = new RmbImpl(); // 创建一个 货币接口的实现类:人民币类 Test.moneyBuy(rmb); // 将人民币类作为实参传递,形参多态 } }
打印结果:
人民币当然也是货币啊