编程思想——面向接口编程(Java语言)


简介

最近学习Java基础的时候被面向接口编程的思想迷住了,自己研究了好一会才搞明白,面向接口太伟大了,我将用我写的第一篇文章记录下这个思想的过程。接下来将通过一个通俗的例子阐述面向接口编程的便利性,虽然实际开发中不太了解,但起码思想是一样的。在阅读本文时大家应有接口实现的基础了,我就不加赘述。

第一阶段

假设有帅哥小明,有一天她苦苦追求的女生说会踢足球和打篮球的男生会好加分。于是小明花重金请来了一个会打篮球和踢足球的金牌教练,代码如下。

篮球类:

public class Basketball {
    public void play(){
        System.out.println("教练教我打篮球");
    }
}

足球类:

public class Football {
    public void play(){
        System.out.println("教练教我踢足球");
    }

请来的金牌教练:

public class Coach {
    public void teach(Football f){
        f.play();
    }

    public void teach(Basketball b){
        b.play();
    }
}

 这时候小明只需在Main类中调用这个教练即可,无脑操纵:

public class Main {
    public static void main(String[] args) {
        Coach c=new Coach();
        Basketball b = new Basketball();
        Football f = new Football();
        c.teach(f);
        c.teach(b);
    }
}

       可是后来小明追求的女生说,会打羽毛球,打排球,打棒球的男生都好加分,但请来的教练只会篮球和足球,还好小明找的是金牌教练,马上就能学会其他球类,教练需要马上学习羽毛球、排球、棒球才能教小明。

       这时球类一多,如果再继续在Coach类中新增teach方法的重写,然后每次都要在Main中new不同的球类对象,会显的十分冗杂......,这种代码一写出来就会被枪毙

       这里很容易想到做一个抽象类,将所有的球抽象起来,满足is-a关系的求全部继承这个抽象类Ball

public abstract class Ball {
    public abstract void play();
}

public class Basketball extends Ball {
    public void play(){
        System.out.println("教练教我打篮球");
    }
}

public class Football extends Ball {
    public void play(){
        System.out.println("教练教我踢足球");
    }
}

public class Badminton extends Ball{
    public void play(){
        System.out.println("教练教我打羽毛球");
    }
}

//................................以此类推

此时教练类就不需要重载一个个teach方法,只需将抽象类作为方法的参数传入,利用向上转型与动态绑定的思想,即可实现方法的准确调用。

更新后的教练类:

public class Coach {
    public void teach(Ball ball){
        ball.play();
    }
}

此时小明的调用:

public class Main {
    public static void main(String[] args) {
        Coach c=new Coach();
        c.teach(new Football());
        c.teach(new Basketball());
    }
}

想学什么就new什么给教练的teach方法,教练就马上教你,很方便有木有~

第一阶段到此结束,以上的方法用的还挺不错,真方便啊,到此其实是面向对象的编程思想,可是慢慢的问题又出现了......

第二阶段

由于金牌教练,小明现在可谓是球类的大神了,可是他追求的女生又说,会弹吉他的男生好帅啊,他希望他的男朋友会弹吉他,小明愣住了。

小明苦恼了,他想,自己的教练是球类教练啊,怎么教他弹吉他......于是他与教练商量。

自有转机,谁叫小明请的是金牌教练,教练说他什么都能学,他有办法!!!

现在球类与乐器类不是同一个类,如果像上面那样用抽象类就会显得乱套了,此时走到更高一层的抽象——接口,干脆将球类与乐器类用一个接口Skill(才艺)抽象出来

public interface Skill {
    void play();
}

将所有的乐器、球类去实现这个接口

public abstract class Ball implements Skill {
    public abstract void play();
}

public class Basketball extends Ball {
    public void play(){
        System.out.println("教练教我打篮球");
    }
}
//球类省略...........

public class Guitar implements Skill{
    public void play(){
        System.out.println("教练教我学吉他");
    }
}

教练的方法参数也变成了接口类型

public class Coach {
    public void teach(Skill s){
        s.play();
    }
}

此时小明就完完全全可以信任金牌教练了,他想学什么,只需要教练学会马上就可以教他,点读机教练,哪里不会new哪里

public class Main {
    public static void main(String[] args) {
        Coach c=new Coach();
        c.teach(new Football());
        c.teach(new Basketball());
        c.teach(new Guitar());
    }
}

教练经过与小明的长久交往,他也知道了小明会有一些三分钟热度的爱好,比如学编程(programming),于是教练觉得为此专门开一个类很不划算,因为小明只会学一次(类只用一次),甚至不需要给这个东西专门起名字,因此教练用了匿名内部类。

public class Main {
    public static void main(String[] args) {
        //花重金买来金牌教练
        Coach c=new Coach();
        
        //通过new对象向金牌教练学习
        c.teach(new Football());
        c.teach(new Basketball());
        c.teach(new Guitar());
        
        //对三分钟热度的技能用匿名内部类
        c.teach(new Skill(){
            @Override
            public void play() {
                System.out.println("教练教我学编程");
            }
        });
    }
}

正是由于金牌教练的存在,他追求的女生被小明的才华深深吸引了,牵手成功。

小明的死党二狗听说了之后,心里也想快点找个女朋友,希望也有一门才艺,然后就找了个拳击教练(BoxingCoach类)教他拳击。

public interface Boxing {
    public void boxing();
}


public class BoxingCoach implements Boxing {
    @Override
    public void boxing() {
        System.out.println("专业拳击教练教拳击!");
    }
}


public class Train {

    public void training(Boxing b){
        b.boxing();
    }

    public static void main(String[] args) {
        Train train = new Train();//进行一次训练
        BoxingCoach boxingCoach = new BoxingCoach();//请拳击教练
        train.training(boxingCoach);//由专业教练教拳击

    }
}

后来二狗由于暴脾气与拳击教练闹翻了,于是拳击教练不干了,走人。

二狗来找小明借他的金牌教练,小明一看二狗是面向接口编程就爽快的答应了,他让自己的金牌教练去学拳击(实现Boxing 接口)

public class Coach implements Boxing {
    public void teach(Skill s){
        s.play();
    }
    public void boxing(){
        System.out.println("小明的金牌教练教拳击");
    }
}

随后就可以在训练中使用金牌教练教拳击

public class Train {

    public void training(Boxing b){
        b.boxing();
    }

    public static void main(String[] args) {
        Train train = new Train();//进行一次训练
//        BoxingCoach boxingCoach = new BoxingCoach();//请拳击教练
//        train.training(boxingCoach);//由专业教练教拳击
        Coach coach = new Coach();//请来小明的金牌教练
        train.training(coach);//由金牌教练教拳击

    }
}

 


编者心得:

在编程时,接口没有is-a关系的限制,只要你觉得你的类需要这个功能,就去实现这个接口,就像金牌教练要学拳击就要去实现拳击接口,面向接口编程应用广泛,比抽象类用的更多,个人觉得精华在于方法参数的接口化。

                                                                                                                      灵感来源:CodeSheep

  • 10
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java面向接口编程思想是指在编程过程中,尽量使用接口来定义类之间的交互,而不是直接使用具体的实现类。这种思想可以提高代码的灵活性、可扩展性和可维护性。 Java的核心技术之一是Java接口接口是一种抽象的数据类型,它定义了一组方法的签名,但没有具体的实现。通过实现接口,类可以获得接口中定义的方法,并根据自己的需求进行具体的实现。这样,不同的类可以实现同一个接口,从而实现了多态性。 下面是一个示例,演示了Java面向接口编程思想及其核心技术: ```java // 定义一个接口 interface Animal { void sound(); } // 实现接口的类 class Dog implements Animal { public void sound() { System.out.println("汪汪汪"); } } class Cat implements Animal { public void sound() { System.out.println("喵喵喵"); } } public class Main { public static void main(String[] args) { Animal animal1 = new Dog(); Animal animal2 = new Cat(); animal1.sound(); // 输出:汪汪汪 animal2.sound(); // 输出:喵喵喵 } } ``` 在上面的示例中,定义了一个Animal接口,它包含一个sound方法。然后,通过实现该接口的Dog和Cat类,分别实现了sound方法。在主函数中,创建了一个Dog对象和一个Cat对象,并分别调用了它们的sound方法。由于Dog和Cat类都实现了Animal接口,所以可以将它们赋值给Animal类型的变量,实现了多态性。 通过面向接口编程,我们可以将具体的实现与接口分离,提高了代码的可维护性和可扩展性。同时,面向接口编程也使得代码更加灵活,可以方便地替换不同的实现类。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值