JavaSE基础06-接口

Java接口

前言

使用抽象类和抽象方法,可以控制基类不被实例化,同时控制派生类必须实现基类的抽象方法。
一个类中包含抽象方法,那么这个类就必须是抽象的;抽象类中的每一个抽象方法都必须要被派生类实现,抽象类中的抽象方法要加修饰符abstract;如果我们写一个抽象类,但从来都没有被实现过,那么这个抽象是垃圾代码。抽象类中是可以没有抽象方法的,一旦有抽象方法则规定子类必须要实现其抽象方法;

这里的接口是特指java中的interface;是比抽象类更进一步的抽象;interface接口的所有方法都必须是抽象的;接口中的所有方法默认都是public,且抽象的,所以不用加这两个修饰符;接口中定义的域是静态的,final的;实现接口用implements,表示当前这个类是这个接口的具体细节;implements接口后,实现的方法必须要加public,因为修饰符只能大不能小,不添加修饰符的话,就是默认包下访问权限,是比public小,要编译报错的。

1.完全解耦

当我们编写一个方法,方法接收一个具体类而非接口时,这个方法就只能接收这个类或其子类;如果我们想把方法给另外一个类使用,这个时候我们就要把方法接收的参数定义成接口;
虽然使用基类我们也可以实现多态,但是没有实现完全解耦。

使用基类的案例演示

package com.JavaSE04.demo02.interface_classprocesser;

import java.util.Arrays;

class Processor{
    public String name(){
        return getClass().getSimpleName();
    }
    Object process(Object input){return input;}
}
class Upcase extends  Processor{
    String  process(Object input){return ((String)input).toUpperCase();}
}
class Downcase extends  Processor{
    String process(Object input){return ((String)input).toLowerCase();}
}
class Splitter extends  Processor{
    String process(Object input){return Arrays.toString(((String)input).split(" "));}
}
public class Apply {
    public static void process(Processor p,Object s){//我们现在使用基类,这个方法我们现在只能给这个基类或其派生类去使用;不能给其他类使用
    	//没有做到完全解耦
        System.out.println("Using Processor "+p.name());
        System.out.println(p.process(s));
    }
    public static String s="Disagreement with beliefs is by definition incorrect";
    public static void main(String[] args) {
            process(new Upcase(),s);
            process(new Downcase(),s);
            process(new Splitter(),s);
    }
}

根据上面实验代码,我们有了下面的改进方案:定义一个顶层接口,然后定义一个抽象类作基类,下面有具体类实现细节。

这是接口

package com.JavaSE04.demo02.interfaces.interfaceprocessor;
public interface Processor
{
    String name();
    Object proces(Object input);
}

这个抽象类继承了接口,并在这个编译单元中定义了很多个处理器class

package com.JavaSE04.demo02.interfaces.interfaceprocessor;

import java.util.Arrays;

//这个类的目的是把公共子类的部分,提出来。
public abstract class StringProcessor  implements Processor{
    public String name() {
        return this.getClass().getSimpleName();
    }
    public abstract Object proces(Object input) ;
}
class Upcase extends StringProcessor{

    public String proces(Object input) {//注:这里使用的协变返回类型
        return ((String)input).toUpperCase();
    }
}
class Downcase extends StringProcessor{

    public String proces(Object input) {
        return ((String)input).toLowerCase();
    }
}
class Spliter extends StringProcessor{

    public String proces(Object input) {
        return Arrays.toString(((String)input).split(" "));
    }
}

最后这是测试入口

package com.JavaSE04.demo02.interfaces.interfaceprocessor;

public class apply {
    //这里使用的是接口,这样程序的可扩展性就高很多了。
    //只要实现了这个接口的处理器,都可以传进来。
    //这样我们的方法就不依赖于某一个具体的类
    public static void process(Processor p,Object s){
        System.out.println("Using Processor "+p.name());
        System.out.println(p.proces(s));
    }
    public static String s="Disagreement with beliefs is by definition incorrect";
    public static void main(String[] args) {
        process(new Upcase(),s);
        process(new Downcase(),s);
        process(new Spliter(),s);
    }
}

2.Java中的多重继承

java只能是继承一个类。但可以实现多个接口;Java中的多继承是指实现多个接口,我们可以把这个类称为每个接口下的具体实现类。

在java中extends只能继承一个类。但允许implements实现多个接口
实现多个接口时,必须用逗号隔开;实现接口时,必须把接口中个每一个抽象方法具体实现。
实现多个接口的目的,就是当我们要把new出来的对象向上转型时可以非常灵活。
以下是实验代码

package com.JavaSE04.demo03;
interface  CanFight{
    void fight();
}
interface  CanSwim{
    void swim();
}
interface  CanFly{
    void fly();
}
class ActionCharacter{
    public void fight(){}//这个方法结构完全跟上面接口方法一样。所以下面实现了CanFight接口,而继承ActionCharacter中刚好有这个方法,不用再实现多一次,父类已经有了。
}
//在java中extends只能继承一个类。但允许实现多个接口
//实现多个接口时,必须用逗号隔开
class Hero extends ActionCharacter implements CanFight,CanFly,CanSwim{

    public void swim() {

    }

    public void fly() {

    }
}
public class adventure {
    public static void t(CanFight x){ x.fight(); }
    public static void u(CanSwim x){x.swim();}
    public static void v(CanFly x){x.fly();}
    public static void w(ActionCharacter x){x.fight();}
    public static void main(String[] args) {
        Hero hero = new Hero();//现在hero是全能的,什么都会
        t(hero);
        u(hero);
        v(hero);
        w(hero);
    }
}

接口之间也可以继承,且可以继承多个接口,继承后子接口可以添加新的抽象方法。
以下是实验代码

package com.JavaSE04.demo03;
interface Monster{
    void menace();
}
//额外新增一个接口的原因是:原来的接口已经正在使用,修改正在使用的接口,那么实现这个接口的类就要作出改变,这是很糟糕的。
//接口跟类的区别:子接口可以继承多个父接口,用逗号隔开
interface DangerousMonster extends Monster{
    void destroy();
}
interface Lethal{
    void kill();
}
interface Vampire extends DangerousMonster,Lethal{//实现了多个父接口(多重继承)
        //扩展自己的方法
     void drinkBlooad();
}
class VeryBadVampire implements Vampire{

    public void menace() {

    }

    public void destroy() {

    }

    public void kill() {

    }

    public void drinkBlooad() {

    }
}
//这个类实现了一个子接口,那么就要实现这个子接口本身及其父接口的方法
class DargonZilla implements  DangerousMonster{

    public void menace() {

    }

    public void destroy() {

    }
}
public class HorrorShow {
    static void u(Monster b){b.menace();}
    static void v(DangerousMonster d){d.destroy();d.menace();}
    static void w(Lethal l){l.kill();}
    public static void main(String[] args) {
        DangerousMonster barney = new DargonZilla();
        u(barney);
        v(barney);
        Vampire  edward = new VeryBadVampire();
        w(edward);
    }
}

当接口跟接口组合进行扩展时,可能出现接口名字重复的情况;若出现名称冲突会出现一些相应的信息,会导致程序无法正常运行。
当我们想要去组合或继承,要小心名字冲突,目前没有好的解决方案,除非重新设计名字。
以下是实验代码

package com.JavaSE04.demo03;

interface  I1{void f();}
interface  I2{int  f(int i);}
interface  I3{int f();}
class C{
    public int f(){
        return 1;
    }
}
class C2 implements I1,I2{
    public void f(){
    }
    public int f(int i) {
        return 1;
    }
}
class C3 extends  C implements I2{
    public int f(int i) {
        return 1;
    }
}
class C4 extends C implements I3{//父类的方法结构刚好跟I3接口中的方法结构一样;可选择重写或不重写
    public int f(){return 1;}
}
//class C5 extends C implements I1{//这里会出问题;父类的方法跟父接口的方法名称相同,但结构又不一样,就会报错,是不允许的;
//    public void f(){ }//重写之后,又跟继承父类的方法冲突
//}
//interface  I4 extends I1,I3{//这也是不允许的;名称相同,结构不同,是会出错的;
//    //IDEA错误提示  ‘f()' in 'com.JavaSE04.demo03.I3' clashes with 'f()' in 'com.JavaSE04.demo03.I1'; methods have unrelated return types
//    
//}
public class TestName {
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值