Java基础-为什么要抽象?

来源:互联网 发布:知乎俄罗斯航空发动机 编辑:程序博客网 时间:2024/06/06 02:26

菜鸟Android开发一只,理解较浅,有错误的地方欢迎大佬指正!
从14年到现在,接触Android已经快有3年的时间了,在工作和学习中也逐渐发现了自己的不足之处,java的底子是真的弱的不行。
虽然有了一定的成长,但是这些还远远不够,必须要让自己成为可以独当一面的开发者。
想学的东西太多,耐心却又不够。相信这是很多开发者在初期会遇到的问题,我也一样。常常是捡了芝麻丢了西瓜,并且从未深入研究过。
Ctrl+c/v成为了码字的主要方式,遇到痛点难点直接百度,看到差不多的项目就下载复制一份…反正功能能实现,管他怎么实现的。
越来越久如此这般,让我成为了一个表层开发者,只会应用,而不会创造。一些很基本的东西也是一问三不知,所以决心从现在开始记录自己真正的成长。
要么不做,要做就做到最好。


一位我很尊重的技术大牛曾经告诉我:每过两个月,你去回头review下自己写的代码,你会发现你根本看不懂自己写的是什么。

15年底,开始接手自己的第一个正式项目,最初的代码没有设计模式,没有命名规范,没有注释,没有封装…都是想到啥写啥。比如为了代码能看起来整齐一点儿,我在每个Activity中都写了一个initView()的方法去初始化一些View,并在onCreate()中去调用这个方法。这样做的确没毛病,但是Activity一多,这样的重复编写就在一定程度上拖慢了效率。
emmm…当时的我的确想不出什么办法可以轻松又简便不用这么一遍一遍的编写同样的东西。也在这个时候,第一次认识到了抽象的意义与使用。

什么是抽象?

在生活中,我们能见到许许多多的动物,我家里就养了两只猫,小区里还有很多人养狗,还有许多人会养各种各样的宠物。当我们提到“一只猫”时,我们能想到一压倒炕的橘猫,当我们提到“一只狗”时,也能想到一只阿拉斯加在撕家。
但是,当我们提到“一只动物”时,我们能想到什么呢?
从这里,便引入了抽象(Abstract)的概念。
abstract可以修饰类或者方法:

  • abstract Class Clz 表示这个类为抽象类
  • abstract void function(); 表示该方法是一个抽象方法,这个方法啥也没有,只是等着被实现而已。

如果一个类中有抽象方法,那么这个类必然为抽象类;但是一个抽象类中可以不存在抽象方法,当然这么写也没啥意义…
举个栗子,猫和狗都会撒泼,吃了睡睡了吃,那么放入Java中来看:

//首先,我们先创建一个Cat类,并写入了一些方法。public class Cat{    void action(){        System.out.println("The cat is running!");    }    void eat(String food){        System.out.println("The cat is eating "+food+"!");    }    void sleep(){        System.out.println("The cat is sleeping...");    }}//接着,我们再创建一个Dog类,写入同样的方法。public class Dog{    void action(){        System.out.println("The dog is running!");    }    void eat(String food){        System.out.println("The dog is eating "+food+"!");    }    void sleep(){        System.out.println("The dog is sleeping...");    }}public class MyClass{    public static void main (String args[]){        Cat cat = new Cat();        cat.action();        cat.eat("fish");        cat.sleep();        Dog dog = new Dog();        dog.action();        dog.eat("meat");        dog.sleep();    }}OutPut:The cat is running!The cat is eating fish!The cat is sleeping...The dog is running!The dog is eating meat!The dog is sleeping...

而猫和狗作为动物,具备一系列共同的特性,那么我们再创建一个Animal类。

public abstract class Animal{    abstract void action();    abstract void eat(String food);    abstract void sleep();}//修改之前的代码,让Cat和Dog去继承Animal。public Cat extends Animal{    @Override    void action() {        System.out.println("The cat is running!");    }    @Override    void eat(String food) {        System.out.println("The cat is eating "+food+"!");    }    @Override    void sleep() {        System.out.println("The cat is sleeping...");    }}

此时可以看到,当Cat类继承Animal时,会强制要求你去实现Animal这个抽象类中的抽象方法。
所以我对抽象的理解为:

  • 抽象类不可被实例化
  • 抽象类的存在是为了继承。
  • 抽象类是将一些类中所拥有的共同属性提取出来,并强制让非抽象子类实现。

为什么要用抽象?

当然,看到这儿肯定会有人发出和我当时一样的质疑,为啥要用抽象啊?我直接在类里写方法不一样一样的么,或者直接使用父类继承也可以啊?
但是,存在即合理。要不为啥java的创造者要费了吧劲儿的整出个抽象来,人家不知道比我高到哪里去了。
如果使用父类继承,我们建立一个Animal类,此类含有eat方法,这个时候Animal是可以有实例化对象的,这并不符合我们的设计思想。
其次,我们定义的子类如果直接继承父类,那么他便会拥有父类的eat方法,但是每种动物的进食手段是不一样的,全部继承父类的方法也不合理,如果重写eat方法并添加自己的实现,那么继承该父类也没有什么特别的意义了,更何况子类是可以选择性重写父类的方法,更加偏移了我们的设计理念。
那么换做抽象类继承呢?我们只需要定义一个抽象方法eat,不需要有具体的实现,只需要告诉继承Animal的子类,你是动物,你会吃东西,但是具体吃啥,怎么吃,吃多少,你自个儿看着办。一方面这很符合我们OOP的设计思想,另一方面也约束了代码逻辑,使其更加严谨也更加清晰,同时,在日后review的时候,也能更加提醒自己注意抽象的方法,因为他一定会被子类实现。

emmmm…以上就是我对抽象的大概理解,自己也查阅了相关资料,同时也借鉴了许多前辈们的经验,加上自己的理解,如有错误的地方,欢迎各位大佬指正。

原创粉丝点击