ios 父类接收子类对象 子类实现父类接口_java


1.定义及代码解释

可以参考 菜鸟教程-Java接口 里面讲的很清楚

  • 接口定义了某一批类所需要遵守的规范,本身不是类,而是抽象方法的集合。这些抽象方法用来描述这一批类具有什么功能,但并不给出每个功能的具体实现(抽象方法没有方法体);
  • 接口不能使用 new 实例化一个接口,但是可以声明接口变量:
Comparable x;   x = new Employee(); // 这里 Employee 实现了 Comparable的接口

if(x instanceof Comparable) {       
      System.out.println("ip是实现了IPoto接口的类的对象");   
} // 可以使用判断对象是否具有某个类的特征的instanceof 来判断某个类是否实现了该接口


  • 所有方法(除非这个类被申明为abstract类) ;
  • 接口中可以常量(public static final修饰),但是不能有实例域,实例域应该由实现接口的类来提供;
  • 子接口与可以继承多个父接口,而类不能多继承;
// 1.IPhoto.java
package com.imooc.tel;
/**
 * 具有照相能力的接口
 */
public interface IPhoto {
    //可以有常量,只能是 public static final,可以不显式说明。但不能有实例域,
    public static final int TEMP=10;

    //抽象方法,接口中的方法默认是 public abstract,可以不写
    void photo(); 

    //jdk8新增的默认方法,可以在实现类中重写,并不必须,并可以通过接口的引用调用
    default void connection() {
        System.out.println("我是接口中的默认方法");
    }

    // jdk1.8新增静态方法 可以带方法体,不可以在实现类中重写,可以用接口名调用
    static void stop() {
        System.out.println("我是接口中的静态链接");
    }
}
// 2.INet.java
package com.imooc.tel;
/**
 * 具备上网能力的接口
 */
//接口访问修饰符:public 默认
public interface INet {
    void network();
    int TEMP=23;
}
// 3.Ipad.java
package com.imooc.tel
/**
 * Ipad类实现了IPhoto和INet接口
 */
public class Ipad implements IPhoto,INet{
    @Override
    public void network() {
        System.out.println("Ipad可以上网");
    }

    @Override
    public void photo() {
        System.out.println("Ipad可以拍照");
    }

    //可以重写,并不必须
    @Override
    public void connection() {
        System.out.println("我是INet接口实现类中重写其默认方法的方法");
    }
}
// 4. IPhone.java 要与 IPhoto接口 相区分开 
package com.imooc.tel;
/**
 * IPhone类也实现了IPhoto和INet接口
 */
public class IPhone implements IPhoto,INet{

    @Override
    public void photo() {
        System.out.println("我是IPhone的拍照功能");
    }

    @Override
    public void network() {
        System.out.println("我是IPhone的上网功能");
    }
}


Test.java


package com.imooc.tel;
/**
 * 测试类
 */
public class IpadTest {
    public static void main(String[] args) {
        Ipad ipad1 = new Ipad();
        ipad1.network();
        ipad1.photo();
        System.out.println("=============");

        INet ipad2 = new Ipad(); //如果把 接口当作父类(抽象类)的话,那么这里就很像多态的向上转型实现
        ipad2.network(); // 只能实现调用network()方法
        ipad2 = new IPhone();//
        ipad2.network();
        System.out.println("=============");

        IPhoto iphoto = new IPhone();
        iphoto.photo();
        iphoto = new Ipad();
        iphoto.photo();
    }
}


2.接口存在的意义

  • 弥补Java不能多继承的缺点。类只能单继承,而一个类可以实现多个接口,这就是 抽象类与接口另一个重要的不同
  • 设计实现

1.梅云罗的例子

假如我开了一个宠物粮店,声明所有宠物都可以来我这里买粮食,这就相当于一个接口


// PetPetRestaurant.java 开了一个宠物粮店,声明所有宠物都可以来我这里买粮食,这就相当于一个接口
public interface PetRestaurant {
    public void buy();
}

// DogPet.java 当一只狗看到了,知道自己是宠物,所以它去实现这个接口
public class DogPet implements PetRestaurant {
    @Override
    public void buy() {
        System.out.println("我是狗,我要买狗粮");
    }
}

// CatPet.java 当一只猫看到了,知道自己也是宠物,所以也去实现这个接口
public class CatPet implements PetRestaurant {
    @Override
    public void buy() {
        System.out.println("我是猫,我要买猫粮");
    }
}
// test.java 店小二 待所有实现了我这个宠物店接口的动物,传进来一个PetRestaurant 类型的宠物,注意,这个PetRestaurant 是接口
public class test {
    public void buy(PetRestaurant pet)
    {
        pet.buy();
    }
}

// Tests.java我这个老板出现了,我可以给他们卖粮食了,相当于测试类
public class Tests { public static void main(String[] args) {  
        PetRestaurant dog = new DogPet();  //实例化一个狗,相当于把狗顾客实例化  
        PetRestaurant cat = new CatPet();//实例化一个猫,相当于把猫顾客实例化    
        test t = new test();  //实例化一个店小二  
        t.buy(cat);  //把猫交给店小二  
        t.buy(dog); //把狗交给店小二 
    }
}


你知道吗,整个过程我这个店主其实根本不知道来的到底是猫是狗还是其他什么,我只要有一个店小二,把这些来的不知什么动物都全部交给店小二,店小二就知道怎么去卖了,因为这些狗啊猫啊都实现了我这个宠物店的接口,而店小二就负责接待所有实现了我这个接口的动物。这就有一个好处,假如明天来了一头小猪,只要它实现了我这个接口,我只管交给店小二处理就OK了,我这个店小二根本不需要变化,我这个店主也只需要实例化一下这个动物就OK。你想,假如没有接口,会怎么办,来一个猫,我要去创造一个猫,还要实例化,来一只狗,我要创建一只狗,同样要实例化,还要配备专门的店小二去接待,就会相当麻烦

  1. 天天向上的回答主要说明,接口可以为不同类的顺利交互提供标准。在实际生产环节,写接口的是设计者(架构师),编写业务的普通程序员。
// Calculator.java 张三写了计算器类    
public class Calculator {     
       public double count(double salary,double bonus) { //这里定义的是 count()         
             return salary + bonus;     
       }    
}
// Seller.java 李四定义了营业员类    
class Seller {        
      String name;        
      Calculator calculator;

      public Seller(String name,Calculator calculator) {
            super();
            this.name = name;
            this.calculator = calculator;
      }

      public void quote(double salary,double bonus) {
            System.out.println(name + "说:您好,请支付" + 
            calculator.countMoney(salary, bonus) + "元。"); //这里 李四用了countMoney
   }
}


二者沟通出现错误,计算方法名不同 导致最后Seller调用失败

实现接口的好处是:

同样是上面这个例子,修改一下:


// lcount.java 接口    
public interface lcount {     
      public double countMoney(double salary,double bonus);    
}

// 张三的 Calculator.java 实现接口    
public class Calculator implements Icount {     
       @Overrides        
       public double countMoney(double salary,double bonus) {         
            return salary + bonus;     
       }    
}


这样的话,李四的代码就没问题,因为接口规定了 计算方法名必须为 countMoney()

同时接口可以降低类的依赖性(耦合性),提高彼此的独立性

后面如果 计算器类 改名为 SuperCalculator,那么代码就如下:


// SuperCalculator.java    
public class SuperCalculator implements Icount {        
       @Overrides        
       public double countMoney(double salary,double bonus) {         
             return salary + bonus;     
       }    
}
// Seller.java 李四的代码就只用改一行就行    
class Seller {        
      String name;        
      Icount calculator; //就是这行
       
      public Seller(String name,Calculator calculator) {
          super();
          this.name = name;
          this.calculator = calculator;
      }

      public void quote(double salary,double bonus) {
       System.out.println(name + "说:您好,请支付" + 
        calculator.countMoney(salary, bonus) + "元。");
   }
}


真不知道是哪位神仙设计出这个思想的?卫庄直呼太妙了!!!