接口
1)、接口也是一种“引用数据类型”,编译之后也是一个class字节码文件。
2)、接口是完全抽象的。(抽象类是半抽象)或者也可以说接口是特殊的抽象类。
3)、接口怎么定义?语法?
【修饰符列表】 interface 接口名{
}
例:
interface A{
}
4)、接口可以继承。
例:
interface A{
}
interface B extends A{
}
5)、接口支持多继承,一个接口可以继承多个接口。
例:
interface A{
}
interface B{
}
interface C extends A, B{
}
6)、接口中只包含两部分:
-
(1)常量
-
(2)抽象方法
7)、接口中所有的元素都是public修饰的。
例:
interface MyMath{
public static final double PI = 3.1415926;
public abstract int sum(int a, int b);
}
注:方法前面的public abstract 修饰符可以省略。
例:
interface MyMath{
int sum (int a, int b);
}
常量前面的public static final也可以省略。
例:
interface MyMath{
double PI = 3.1415926;
}
8)、接口中的方法都是抽象方法,所以接口中的方法不能有方法体。
例:
interface MyMath{
void doSome(){}
}//编译错误
9)、类和类的关系叫继承,类和接口关系叫实现。【仍可以将“实现”看做继承】
继承使用extends关键字完成。实现使用implements关键字完成。
10)、当一个非抽象的类实现接口的话,必须将接口中所有的抽象方法全部实现/覆盖/重写.
例:
interface MyMath{
public static final double PI = 3.1415926;
public abstract int sum(int a, int b);
}
class MyMathImp implements MyMath{
public int sum(int a, int b){
return a + b;
}
}
注意:若将MyMathImp类中的sum方法改为以下形式:
class MyMathImp implements MyMath{
int sum(int a, int b){
return a + b;
}
}
则会出现错误:“正在尝试分配更低的访问权限”。
示例:
package java核心技术;
public class ImplementsTest01 {
public static void main(String [] args) {
MyMath m1 = new MyMathImp();
System.out.println(m1.sum(10, 20));
System.out.println(m1.sub(10, 20));
}
}
interface MyMath{
public static final double PI = 3.1415926;
public abstract int sum(int a, int b);
public abstract int sub(int a, int b);
}
class MyMathImp implements MyMath{
public int sum(int a, int b) {
return a + b;
}
public int sub(int a, int b) {
return a - b;
}
}
运行结果:
30
-10
11)、一个类可以同时实现多个接口。
这种机制弥补了Java中单继承带来的缺陷。
例:
interface A{
}
interface B{
}
interface C{
}
class D implements A, B, C{
}
12)、没有继承关系的两个接口,可以相互转换。编译阶段没有问题,但是运行时可能出现ClassCastException异常【类型转换异常】
```go
public class Test01{
public static void main(String [] args){
A a = new D();
B b = new D();
a.m2();//编译错误,因为A中没有m2方法
B b2 = (B) a;//编译没问题
b2.m2();//运行成功
}
}
interface A{
}
interface B{
void m2();
}
interface C{
}
class D implements A, B, C{
public void m2(){
}
}
注:向下转型养成好习惯,转型之前先if + instanceof判断。
13)、接口、继承都存在的话,extends在前,implements在后,请看以下代码示例:
package java核心技术;
public class ImplementsTest02 {
public static void main(String [] args) {
Flyable f = new Cat2();
f.fly();
}
}
//动物类:父类
class Animal2{
}
//接口:可飞翔
interface Flyable{
void fly();
}
//动物子类:猫类
//实现接口,变成飞猫
class Cat2 extends Animal2 implements Flyable{
public void fly() {
System.out.println("起飞了起飞了");
}
}
运行结果:
起飞了起飞了
14)、使用接口,写代码的时候,可以使用多态(父类型引用指向子类型对象)
15)、接口在开发中的作用
类似于多态(面向抽象编程,降低程序的耦合度,提高扩展力)
即“解耦合”!!任何一个接口都有调用者和实现者,接口可以将调用者和实现者解耦合。调用者面向接口调用,实现者面向接口编写实现。
16)、类型和类型之间的关系
-
-is a
Cat is a Animal.(猫是一个动物) 凡是能够满足is a 的是“继承关系”。 A extends B
-
-has a
I has a Pen.(我有一只钢笔) 凡是能够满足has a 关系的表示“关联关系” 关联关系通常以“属性”的形式存在。 A{ B b; }
-
-like a
Cooker like a FoodMenu.(厨师像一个菜单一样) 凡是能够满足Like a 关系的表示“实现关系” 实现关系通常是:类实现接口。 A implements B
17)、抽象类和接口有什么区别?
-抽象类是半抽象的 接口是完全抽象的 -抽象类中有构造方法 接口中没有构造方法 -接口和接口之间支持多继承 类和类之间只能单继承 -一个类可以同时实现多个接口 一个抽象类只能继承一个类(单继承) -接口中中允许出现常量和抽象方法。
一个简单实例:
package java核心技术;
public class ImplementsTest03 {
public static void main(String [] args) {
//创建厨师对象
FoodMenu cooker1 = new AmercCooker();
//创建顾客对象
Customer3 customer = new Customer3(cooker1);
customer.order();
}
}
public interface FoodMenu{
void xiHongShiChaoJiDan();
void yuXiangRouSi();
}
class Customer3{
FoodMenu foodMenu;
public Customer3() {
}
public Customer3(FoodMenu foodMenu) {
this.foodMenu = foodMenu;
}
public void setFoodMenu(FoodMenu foodMenu) {
this.foodMenu = foodMenu;
}
public FoodMenu getFoodMenu() {
return foodMenu;
}
public void order() {
foodMenu.xiHongShiChaoJiDan();
foodMenu.yuXiangRouSi();
}
}
class ChinaCooker implements FoodMenu{
public void xiHongShiChaoJiDan() {
System.out.println("中餐西红柿炒鸡蛋");
}
public void yuXiangRouSi() {
System.out.println("中餐鱼香肉丝");
}
}
class AmercCooker implements FoodMenu{
public void xiHongShiChaoJiDan() {
System.out.println("西餐西红柿炒鸡蛋");
}
public void yuXiangRouSi() {
System.out.println("西餐鱼香肉丝");
}
}
运行结果:
西餐西红柿炒鸡蛋
西餐鱼香肉丝