美文网首页
抽象类和接口的使用

抽象类和接口的使用

作者: IT废柴 | 来源:发表于2017-12-13 09:44 被阅读0次

    开篇废话

    入职后一直研究Android framework的东西,大概花了一个月鼓捣了一个系统应用“应用双开”。虽然也是敲代码,但是主要是在Android源码中进行修改,也可以说很久没用java去写一个完整的东西了。近来公司有个小工具需要开发,上头应该觉得功能很简单,所以让我一个人开发。具体功能需求不便透露,主要是一个windows应用。本来我打算用C#写,但是老大说最好用java,最终选了java swing来开发。这是一个很古老的东西,反正我也不熟悉,在大概学习了swing的组件使用之后,就开始动手coding了。

    java思想

    其实不管java也好,其他面向对象语言也好。面向对象的思想就是分工而治,统一管理。这里我就不吹逼面向对象了,毕竟能力有限,吹逼能力有限,道行尚浅。大家记住这几个字分工而治,统一管理

    例如

    说一千道一万,眼见为实耳听为虚。我写的工具中有这么一项需求。大致类似于,我要写满汉全席的食谱,总共一百零八道菜,每道菜都需要配图(UI)和做法(文本),最终写到一个册子中(文本汇总)。

    需求分析:

    1.一百零八道菜,每个菜都不同,应该对应着有108个类吧。
    2.每道菜都需要配图和做法,对应着每个类都应该有一个pic()方法和cook()方法吧。
    3.最终写到一个册子中。汇总:调用所有类的cook()方法,写到一个文本中。

    代码设计

    一定要记住,不要忙于写代码,而是搞清楚功能逻辑,不然写到一半改需求是真的很要命,我就吃了这个亏,好在我前期代码结构设计还算可以,不至于重头来过。

    言归正传:108道菜,每道菜都不同,如果没有重样的菜,就意味应该有108个类。每个类都有pic()和cook()方法,说明这是共用类,汇总的时候去调用每个类的cook()方法。
    按照道理讲功能的逻辑是这样没错了,如果这108类每个类都不一样的话,这108类看来是必不可少了,pic()和cook(),属于类的方法,无可厚非,但是汇总时,我总不能把每个类都实例化一遍然后去调用各自的cook方法吧。所以这时候,java的抽象类和接口就得派上用场了。抽象类和接口都是用于类的继承,抽象类只能单继承,接口可以多继承,这些基础的概念,想必大家都懂,不懂没关系,可以上网去查啊http://www.jianshu.com/p/038f0b356e9a
    但是值得去讲的是:抽象类和接口中都是抽象方法,就是没有实现的方法,语法上支持你去调用这个方法,但是最终调用的是继承了该类或接口并实现了该方法的类。
    所以:我们可以这样做,这些如何灵活运行接口和抽象类就看各自的本事了,我大致讲解一下我的做法。

    首先我定义了一个抽象类
    public abstract class Food {
    
        public String type = "";
    
        public Food() {
        }
    
        abstract public String cook();
        abstract public void pic();
    }
    

    其中有两个未实现的抽象方法,因为考虑到108到菜也分菜系,所以用了type变量用来标识菜系。
    现在我们要做两个菜系的菜,粤菜,和川菜。不管他们是哪个菜系,但是他们都属于food,于是就呈现出一种继承关系。

    然后定义粤菜类和川菜类:
    public abstract class YueCai extends Food {
    
        public YueCai() {
            type = "YueCai";
        }
    }
    
    public abstract class ChuanCai extends Food {
    
        public ChuanCai() {
            type = "ChuanCai";
        }
    }
    

    因为他们是food类的子类,所以他们也含有food类的pic()和cook()方法。
    既然要写成菜谱,那么我们是否应该有一个专门来写菜谱的人。

    接着我们来定义cooker类
    import java.util.List;
    
    public class Cooker {
    
        private List<Food> foods = null;
        public Cooker() {
        }
    
        public void addFood(Food food) {
            foods.add(food);
        }
    
        public void write() {
            StringBuffer cookBook = new StringBuffer();
            for(Food food : foods) {
                cookBook.append(food.cook());
            }
        }
    }
    

    这里的cooker类,就是统一管理的类,首先是维护了一个List,类型是Food类,Food是抽象类,就是告诉大家,我这里要装的菜肴,但具体是什么菜,你实际放什么菜那就是什么菜,我这里不关心。
    然后定义了add方法,用于往List中填充内容,write()函数,就是写菜谱了,循环遍历List<Food>,依次调用Food的cook方法。这里就解决了,108道,每道菜不同,不需要我分别调用这108个类的方法,因为我在这里统一调用了抽象类Food的抽象方法cook(),但是这个方法是未实现的方法,所以它最终调用的是实现了这个方法的类。那么到底哪个类实现了该方法,而又是如何才能调用到的呢。

    上面写的所有的类都是代码结构的搭建,说白了就是一群只知道说,不去做事的家伙

    那么我们来定义踏实干活的人吧
    
    public class MapoDouFu extends ChuanCai{
    
        public MapoDouFu() {
        }
    
        @Override
        public String cook() {
            return "mapoDoufu";
        }
    
        @Override
        public void pic() {
            
        }
    
    }
    
    
    public class YanjuChicken extends YueCai {
    
        public YanjuChicken() {
        }
    
        @Override
        public String cook() {
            return "YanjuChicken";
        }
    
        @Override
        public void pic() {
            
        }
    
    }
    

    我们这里定义了两道菜的类,一个MapoDoufu,一个YanjuChicken。他们分别继承了ChuanCai类和YueCai类,而ChuanCai类和YueCai类都是继承自Food类,所以他们都是Food类的子类。并且都是Food类的最终实现类。

    然后我们在合适的地方去调用Cooker的addFood()方法
    Cooker cooker = new Cooker();
    MapoDouFu mapoDouFu = new MapoDouFu();
    cooker.addFood(mapoDouFu);
    YanjuChicken yanjuChicken = new  YanjuChicken();
    cooker.addFood(yanjuChicken);
    

    这里就是java多态的体现,我们定义addFood()方法时,形式参数是Food类,但是在调用时实际传入的Food类的子类MapoDoufu和YanjuChicken类。所以当我们去调用wirte()时,也将调用的实际传入类的cook()方法。
    这是简单的对抽象类一个应用场景的介绍,同样,接口也是可以这样使用的。原理是一样的,我这里就不复述了。

    public interface Food {
        public void pic();
        public String cook();
    }
    
    public class YanjuChicken implements Food {
    
        public YanjuChicken() {
        }
    
        @Override
        public void pic() {
            
        }
    
        @Override
        public String cook() {
            return "YanjuChicken";
        }
    
    }
    
    public class MapoDoufu implements Food {
    
        public  MapoDoufu() {
        }
    
        @Override
        public void pic() {
            
        }
    
        @Override
        public String cook() {
            return "MapoDoufu";
    
    }
    
    public class Cooker {
    
        private List<Food> foods = null;
        public Cooker() {
        }
        public void write() {
            StringBuffer cookBook = new StringBuffer();
            for(Food food : foods) {
                cookBook.append(food.cook());
            }
        }
        public void addFood(Food food) {
            foods.add(food);
        }
    
    }
    

    至于type的作用,本篇没有体现出来,而是想告诉大家要有抽象分类的思想。

    这里只涉及到接口和抽象类最基础的用法,还有回调,内部类等等的用法,这些东西也是很常用的,后续我会更新相关的文章,如有错误的地方,欢迎大家批评指正,不胜感激!如有疑惑的地方,也欢迎大家讨论。

    相关文章

      网友评论

          本文标题:抽象类和接口的使用

          本文链接:https://www.haomeiwen.com/subject/xjwnixtx.html