java接口

一,接口注意点

  1. 接口不是类,而是对类一组需求描述,这些类要遵从接口描述的统一格式进行定义
  2. 接口(interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。
  3. 接口包含类要实现的方法,类描述对象的属性和方法。
  4. 除非实现接口的类是抽象类,否则该类要定义接口中所有的方法
  5. 如果一个类既要继承另一个类又要实现一个接口,只能先继承再实现
class son extend father implements interface{
//    
}

 

二,接口与类的区别

  1. 接口不能实例化对象,但是可以被实现。。
  2. 接口没有构造方法。
  3. 接口内所有方法必须是抽象方法。
  4. 接口不是被类继承,是被类实现。
  5. 接口支持多继承,类不能。

 

三,接口与类的相似点

  1. 一个接口有多个方法。
  2. 接口文件保存在.java结尾的文件夹中,文件使用接口名,字节码保存在.class结尾文件中。
  3. 接口相应的文件需保存在与包名相匹配的结构目录中

 

四,接口特性

  • 不能使用new运算符实例化一个接口

//错误的 x = new Comparable(.....); //Comparable是一个接口

  • 接口内能声明变量
Comparable a; 
//接口变量必须引用实现了接口的类对象,或者就是一个空指针
a = new Employee(.....);
  • 可以使用instanceof检查一个对象是否属于某个特定类
//测试左边的对象是否是右边类的实例
if(anObject instanceof Comparable)
  • 接口可扩展
public interface Moveable
{
  void move(double x,double y);    
}

//扩展一个叫做Powered的接口
public interface Powered extends Moveable
{
  double milesPerGallon();  
}
  • 接口不能包含实例域或静态方法,但是可以包含常量(java8可以加静态方法了,但是这有违将接口作为抽象规范的初衷)
//接口中的方法自动的被设置为public abstract
//接口中的变量都自动设为public static final

public interface Powered extends Moveable
{
    double milesPerGallon();  //等价于 public abstract double milesPerGallon();
    double num = 16.6;      //等价于 public static final double num = 16.6;
}

 

五:简单案例

public interface Person{   //接口 
    void father();
    void mother();
}                                    
public class Family implements Person{    //实现类

    public void father(){
    System.out.println("我是爸爸");
    }
    
    public void mother(){
     System.out.println("我是妈妈"); 
    }  
}                                                                

 

 

六:默认方法

  • 为借口方法提供一个默认实现,用default修饰符修饰
public interface Comparable<T>{
    default int compareTo(T other){
        return 0;
        }
}
  • 默认方法的作用
一旦接口需要发生变化,实现这些接口的类也就需要更新,但是如果是很多类,那这样操作起来就很麻烦。比如Collection接口为例,在Java SE8中,为了这个接口添加了一个默认方法stream方法,假设stream方法不是一个默认方法,那Bag类将不能编译(Bag类并没有实现这个方法),为接口增加一个非默认方法不能保证“源代码兼容”,假设不重新编译这个类,而是使用原先的一个包含这个类的JAR文件,这个类仍能正常加载和构造Bag实例(尽管没有stream方法),但是在Bag实例上调用这个方法是,就会出现AbstractMethodError。如果将stream设为默认方法将会解决上面俩个问题。
  • 解决默认方法冲突
如果先在一个接口中将一个方法设为默认方法,又在一个超类或者另一个接口定义了同样的方法,会是什么情况?
  1. 超类优先。如果超类提供了一个具体方法,同名而且有相同参数类型的默认方法会被忽略。
  2. 接口冲突,俩个接口提供了同名且参数类型(不论是否是默认参数)相同的方法,必须覆盖这个方法来解决
interface School{
  defualt String getName(){
     return getClass().getName()+" "+hasCode();
         }
}

class Student implements School,Family{  
//School和Family接口都有getName默认方法  
    public String getName(){
        return School.super.getName();
        }
}                                                            

 

 

七:问题与扩展

  • 为什么还要用接口,不是已经有抽象类了吗?
//比如
abstract class Comparable{
  public abstract int compareTo(Object other);  
}

//然后 Employee类再扩展这个抽象类,并实现方法
class Employee extends Comparable{
    public int compareTo{
    .......
    }
}


//为什么不这样?

 

因为抽象类表示通用属性存在这样一个问题:每个类只能扩展一个类,假如Employee类已经扩展一个类Person了,就不能扩展其他类了
class Employee extends Person,Comparable    //错误
class Employee extends Person implements Comparable    //正确
  •  Comparable接口
public interface Comparable{
    int compareTo(Object other)
}

//在java SE5.0中,Comparable接口已改进为泛型类型
public inteface Comparable<T>{
    int compareTo(T other)    //int compareTo(Employee other)
}                                      

//以下是实现方法
public int compareTo(Object otherObject){

      Employee other = (Employee) otherObject;

      //调用静态方法Double.compareTo 比较salary与other salary返回-1 0 1
      return Double.compare(salary,other.salary);
}

//最好用这个,泛型
class Employee implements Comparable<Employee>{
    public int compareTo(Employee other){
    return Double.compare(salary,other.salary);
    }
}
  • 为什么不能再Employee类中直接提供compareTo方法,而要去实现Comparable接口?
java是强类型语言,在调用方法时将会检查这个方法是否存在。sort方法可能存下面的语句:
//Employee [] a = new ....  调用
if
(a[i].compareTo(a[j])>0){ ............ }
为此,编译器需确认a[i]一定有compareTo方法,因为每个实现Comparable接口的类都必须提供这个方法的定义,换一种角度,如果将Array类中的sort方法定义为接受一个Comparable[]数组就可以在使用元素类型没有实现Comparable接口的数组作为参数调用sort方法。在这种情况下sort可以接受一个object[]数组,并对其进行笨拙的转换,如果a[i]不属于实现了Comparable的类。虚拟机将会抛出异常
//案例
public class EmployeeSortTest {

    public static void main(String[] args) {
        
        Employee[] staff = new Employee[3];
  
        staff[0] = new Employee("hjj",20000);
        ...
        //注意Employee类里是没有sort方法的,确认staff[i]是否有compareTo方法,有,并且a[i]属于实现了Comparable的类
     //Arrays类继承了Comparable接口
Arrays.sort(staff); } }
public class Employee implements Comparable<Employee>{
    
    private String name;
    private double salary;
    .....
    .....
    //实现compareTo方法
    public int compare(Employee other) {
    return Double.compare(salary,other.salary);
    }
    
}

 

posted @ 2019-04-02 20:21  黄骏捷的博客  阅读(538)  评论(0编辑  收藏  举报