抽象类与接口

文章出自:安卓进阶学习指南
作者:Milo
审核者: Struggle
完稿日期:2017.10.24

常见问题

  • 什么时候创建抽象类?什么时候创建接口?
  • 它们之间的区别?
  • 设计框架时该如何选择?

-- 如果以上问题在脑海中有些模糊的话,那就让我们一起带着问题来学习一下。假如与你的理解有出入或者不对的地方欢迎指出,谢谢。

1.基本概念

抽象方法:
使用abstract关键字修饰,仅有声明没有方法体的方法称为抽象方法。

public abstract void f();

抽象类:
包含抽象方法的类叫做抽象类,如果一个类包含一个或者多个抽象方法,该类必须被限定为抽象的。抽象类可能不包含抽象方法。

 public abstract class TestAbstract {
    private String a = "test";
    abstract void test();
    public String  test2(){return a;}
}

接口:
接口是抽象类的一种特殊形式。使用interface修饰。

public interface TestInterface {
    void test();
    void test2();
} 

2.案例分析

  • 抽象类

我们都知道人的种类分为很多种,有黄种人、黑种人等等。他们都属于人类,它们都有一个共同的特征就是说话、走路、睡觉。从中我们不难看出人类是一个很抽象的概念,可以把人类抽象出来,他们具有共同的特征:说话、走路、睡觉。

public abstract class Human {
    abstract void speak();
    abstract void walk();
    abstract void sleep();
}
public class YellowHuman extends Human{
    @Override
    void speak() {
    // speak Chinese
    System.out.println("YellowHuman speak Chinese");
}
    @Override
    void walk() { }
    @Override
    void sleep() {}
}
public class BlackHuman extends Human{
    @Override
    void speak() {// speak English
    System.out.println("BlackHuman speak English");
    }
    @Override
    void walk() { }
    @Override
    void sleep() {}
}
public class Test {  
    public static void main(String[] args) {  
        Human h1 = new YellowHuman();  
        Human h2 = new BlackHuman();  
        a1.speak();  
        a2.speak();  
    }  
}
------------------------------------------------
output:
YellowHuman speak Chinese
BlackHuman speak English
  1. 抽象类是由子类具有相同的一类特征抽象而来,也可以说是其基类或者父类;
  2. 抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为public;
  3. 抽象类不能用来创建对象;
  4. 抽象方法必须由子类来实现;
  5. 如果一个类继承于一个抽象类,则子类必须实现父类的抽象方法,如果子类没有实现父类的抽象方法,则必须将子类也定义为抽类;
  6. 抽象类还是很有用的重构工具,因为它们使得我们可以很容易地将公共方法沿着继承层次结构向上移动。
  • 接口

沿着上面案例,我们都知道黄种人擅长乒乓球,黑种人擅长长跑。

public interface TableTennis {
    void tableTennis();
}
public interface Run {
    void run();
}

public class YellowHuman extends Human implements TableTennis{
    @Override
...
...
    @Override
    public void tableTennis() {}
}
public class BlackHuman extends Human implements Run{
    @Override
...
...
    @Override
    public void run() {}
}

思考 ?
为什么这里没有在Human里面添加tableTennis和run的抽象方法或者接口,而是使用两个单独的接口?

public abstract class Human {
     abstract void speak();
     abstract void walk();
     abstract void sleep();
     abstract void tableTennis();
     abstract void run();
 }
 或者
public interface class Human {
     abstract void speak();
     abstract void walk();
     abstract void sleep();
     abstract void tableTennis();
     abstract void run();
      }

tableTennis和run这两种行为是YellowHuman和BlackHuman各自最擅长的行为,如果抽象在Human里面,那么就会出现黄种人可能不擅长跑步,黑人可能不擅长乒乓球的情况,一旦各自擅长的东西发生改变,依赖Human的子类就会发生变化。这样就违反了面向对象设计中的核心原则 ISP (Interface Segregation Principle)。点击参考

  1. 接口是抽象类的延伸,Java为了保证数据安全性是不能多继承的。也就是一个类只有一个父类。但是接口不同,一个类可以同时实现多个接口,不管这些接口之间有没有关系,所以接口弥补了抽象类不能多继承的缺陷。推荐接口和抽象类同时使用,这样既保证了数据的安全性又可以实现多继承;
  2. 接口的所有法访问权限自动被声明为public;
  3. 接口中可以定义“成员变量”,会自动变为public static final修饰的。可以通过类命名直接访问:ImplementClass.name,不推荐在接口中定义成员变量;
  4. 实现接口的非抽象类必须实现接口中所有方法,抽象类可以不用全部实现;
  5. 接口不能创建对象,但可以申明一个接口变量,方便调用;
  6. 完全解耦,可以编写可复用性更好的代码。

3.抽象类与接口的区别

  • 语法层次
 public abstract class TestAbstract {
    private String a = "test";
    abstract void test();
    public String  test2(){
    return a;
    }
}

public interface TestInterface {
    void test();
    void test2();
} 

在语法层次抽象类与接口的区别主要体现在写法上,且抽象类可以声明各种范围的成员,可以定义非抽象方法。接口只能声明被static final 修饰的成员变量,一般不推荐接口中声明成员变量。在某种程度上接口是抽象类的特殊化。

  • 设计层次
  1. 抽象层次不同
    抽象类是对类抽象,而接口是对行为的抽象。抽象类是对整个类整体进行抽象,包括属性、行为,但是接口却是对类局部行为进行抽象。

  2. 跨域不同
    抽象类所跨域的是具有相似特点的类,而接口却可以跨域不同的类。抽象类所体现的是一种继承关系,考虑的是子类与父类本质“是不是”同一类的关系。而接口并不要求实现的类与接口是同一本质,它们之间只存在”有没有“的关系。

  3. 设计层次不同
    抽象类是自下而上的设计,接口是自上而下。

总结

  1. 抽象类在java语言中所表示的是一种继承关系,一个子类只能存在一个父类,但是可以实现多个接口。
  2. 抽象类表示的是"is-a"关系,接口表示的是"like-a"关系。点击参考
  3. 抽象类是对类抽象,而接口是对行为的抽象。

Thanks

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 207,248评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,681评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,443评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,475评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,458评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,185评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,451评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,112评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,609评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,083评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,163评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,803评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,357评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,357评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,590评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,636评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,925评论 2 344

推荐阅读更多精彩内容

  • 一、抽象类 1、抽象类含义的概括: 当多个类出现相同功能时,但功能主体不同,这样可以向上抽取,抽取时只抽取功能定义...
    玉圣阅读 824评论 0 6
  • 你很清楚的知道什么时候用抽象类,什么时候用接口么?p.s. 多文字预警! 1 抽象类和接口简介 1.1 抽象类 ...
    Sharember阅读 2,345评论 9 55
  • 一、抽象类: 抽象类是特殊的类,只是不能被实例化;除此以外,具有类的其他特性;重要的是抽象类可以包括抽象方法,这是...
    FrozenSunset阅读 500评论 0 3
  • 对于面向对象编程来说,抽象是它的一大特征之一。在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类。接口...
    Q南南南Q阅读 365评论 0 3
  • 抽象类abstract 抽象类:如果一个类没有足够的信息来描述一个具体的对象,而需要其他具体的类来支撑它,那么这样...
    jadefly阅读 356评论 0 0