首先简单的介绍一下抽象类:

定义是很简单的,我们这里不写官方的语言,我自己看着都烦,我们就用白话介绍,抽象类本质是一个类,没问题,那么类里面一般都是有方法的,方法包括方法名和方法体,这是常识对不对,那么什么是抽象类呢?如果一个类里面有一种方法只有方法名却没有方法体,这样的类就是抽象类!

举个例子:

public abstract class TestAbstract {
//这是一个抽象方法,
public abstract void run();
//当然这里面也可以是普通的方法
public void eat() {
System.out.println("我是一个在抽象类里面的普通方法");
}
}

这里为了区别普通的类,我们一般加abstract这个关键字,我们就认为他是一个抽象类。既然是一个类,那么普通类的属性他都有,它也可以写普通的方法。

这里就有人说了,那这个有什么用呢?没有实现体,就是调用也没用啊,JDK也想到这个了,所以呢他是不让你直接实例化调用的,因为没用啊,对吧,这也是为什么抽象类不可以直接实例化自己,这里说实例化自己有些人不明白,说人话就是不可以自己创建一个自己的对象出来,他只能是子类的引用来创建父类的对象。

举个例子:

public static void main(String[] args) {
/**
* 抽象类是不可以自己实例化自己的,只能实例化自己的子类,因为只有子类才有方法的实现,自己实例化自己是没有意义的。况且就是自己
* 里面有普通方法的实现,他的子类都是可以使用的。
*/
TestAbstract t = new TestA01(); }

回到之前的话题,既然有些方法不可以实现,写了做什么呢?难道就为了那几个可以实现的方法?当然不是的,这里的抽象类是为了子类更好的实现。

我们举个简单的例子:我们有一个动物的类,里面有一个Run的方法,这个时候我们需要继承他,一只狗说我会跑,老虎说我也会跑,孔雀说我也会跑,这个时候每一个子类都要继承他,而且由于Run方法已经被父类实现了,所以每一个都要重写方法体,是不是很麻烦,这个时候JDK就说了,既然那么多类需要继承他,我直接不实现这个方法,你们谁用谁实现算了。这个就是抽象类存在的意义!

说的比较官方一些的话,就是抽象类可以将设计和实现分离,你写你的抽象类,我写我的实现方法。这也是为什么说抽象方法必须被继承才有意义!

举个例子:

class TestA01 extends TestAbstract{
/**
* @Override 是注解,JDK5.0以后的新特性,重写的意思,也就是说,如果是注解了的话,就是重写的方法,名字是不可以改的, 如果去掉注解,说明不是重写的方法
* 名字是可以改掉的。
*/
@Override
public void run() {
System.out.println("我是子类的run()");
} }

总结一下:

有抽象方法的类必然是抽象类

抽象类不可以被实例化,不能被new来实例化抽象类

抽象类可以包含属性,方法,构造方法,但是构造方法不能用来new实例,只能被子类调用

抽象类只能用来继承

抽象类的抽象方法必须被子类继承

下面我们说一下接口:

接口是我觉得Java里面相当伟大的一个发明,为什么呢?听我说完,接口我们可以认为本质也是一个类,只是修饰符改为了interface,类的修饰符是Class而已,那么接口是干嘛呢?前面讲了抽象类的使用,接口就是一个比抽象类还要抽象的类,前面说抽象类里面可以写普通的方法,说明还不够抽象,抽象的不够彻底,接口说干脆一不做二不休,规定只能写抽象方法算了,所以说接口是比抽象方法更抽象的类。

举个例子:

public interface MyIinterface {
/**
* 接口里面只有常量和抽象方法
*/
/*public static final 接口中常量定义时都有这个,写不写都是这样*/String MAX_GREAD = "BOSS";
int MAX_SPEED = 120;
/*public abstatic 这里一样写不写都是public,因为不用public的话没有意义*/ void test01();
public int test02(int a, int b); }

有的人说不能被继承,不是和抽象类一样吗?为什么不写abstract关键字呢?不能被普通方法调用,不是静态变量吗?是的,说的都对,所以JDK这里不管你写不写,都是默认前面有这些修饰词的,上面我写的很明白!

上面有句话说不同public的话没有意义,其实写到这里我们可以基本认为接口和抽象类是一种规则了,它规定你这样用,你只要继承或者实现,就必须要按照他的来,所以我们对应到现实生活中的话,就是说是一种规则,既然是规则就是给别人看的,你一个公司制定出来了规章制度,不公布,别人怎么遵守?一个道理,如果不用public修饰别人引用不到,和不规定是一样的。所以JDK也明白,所以这里的方法你写不写public他都默认帮你加上!

下面讲实现

我们说了,抽象类也好,接口也好,不继承,不实现都是没有意义的,但是因为接口里面只有抽象方法,所以他必须被实现才有意义,不然就会被垃圾回收机制System.gc给回收掉,前面的文章说过了垃圾回收的原理,这里不做赘述,但是为什么不继承呢?有人说了?既然要被实现里面的方法,直接继承不行了吗?是的,但是类的继承只能是单继承,所以,如果一个类里面有很多的接口,怎么做?所以只能是实现!

但是有人说了,如果很多接口,最后一个继承了上面的所有接口,那我实现的时候是不是需要实现所有接口的方法?答案是肯定的:

举个例子:

package com.gaojizu.TestInterface;
/**
* 测试接口的多继承
* @author admin
*
*/
public interface InterFaceA { void aaa();
}
/**
* 接口B
* @author admin
*
*/
interface InterFaceB{
void bbb();
}
/**
* 接口C
* @author admin
*
*/
interface InterFaceC extends InterFaceA,InterFaceB{
void ccc();
}
/**
* 实现类
* @author admin
*
*/ class TestClass implements InterFaceC{ @Override
public void aaa() {
System.out.println("TestClass.aaa()"); } @Override
public void bbb() {
System.out.println("TestClass.bbb()"); } @Override
public void ccc() {
System.out.println("TestClass.ccc()"); } }

其实这里也不难理解,继承了就是拥有了父接口的抽象方法,自然就必须实现他。

那有人说了,我这里如果在子类里面声明了一个变量,那我直接用父接口的对象调用行不行呢?

举个例子:

class Plane implements FlyAble{

	String name;
@Override
public void fly() {
System.out.println("我可以飞"); } }

这里有一个name,我测试的时候是不是可以直接使用呢?当然不是,需要强制转换:

看例子:

public static void main(String[] args) {
/**
* 这里的接口是不可以自己实例化自己的,原因和抽象类是一样的,里面只有抽象方法,没有实现的,所以是实例化没有意义的
* 那么直接f是不可以调出子类里面的属性的,原因很简单,他是FlyAble的对象,那么他就只能找到自己下面的属性和方法
* 是没有办法知道子类的属性和方法的,想知道的话,就强制转换为子类的对象就行了。下面是例子
*/
FlyAble f = new Plane();
//强制转换为Plane类
Plane p = (Plane)f;
p.name = "test";
}

其实这里用我们生活中的例子也是一样可以理解的,我们有一个会飞的类,他创建了一个天鹅的对象出来,天鹅说我会下蛋,那按照我们代码的逻辑来想,会飞的应该都会下蛋,显然不是,飞机也会飞,但是不会下蛋,怎么可以下蛋呢?将实例化出来的对象给一个具体使用的类,也就是天鹅!这里也是多态的一个体现,你给一个笼统的概念,然后具体的使用是什么就是什么的思想!

最后一点:实现是可以多实现的!

前面我们说接口的继承是可以多继承的,看明白,是接口可以多继承,类一样是单继承,实现是可以多实现的,你说我既可以飞,也可以跑,飞和跑在两个接口里面怎么办?可以同时实现:

看例子:

public interface FlyAble {

	int MAX_SPEED = 11000;
int MIN_SPEED = 1;
void fly();
}
/**
* 攻击的接口
* @author admin
*
*/
interface Attack{
void tack();
} class Plane implements FlyAble{ String name;
@Override
public void fly() {
System.out.println("我可以飞"); } }
/**
* 可以实现多个接口
* @author admin
*
*/
class men implements FlyAble,Attack{ @Override
public void tack() {
System.out.println("我可以攻击"); } @Override
public void fly() {
System.out.println("我可以飞");
} }

那么接口存在的意义就不用说了吧,很明显了,为了更好的将设计与实现分离。

设计师写完需要的接口,别的不用管了,怎么实现是下面的事情了,这样不仅仅可以提高开发效率,也可以更好的维护。当然如果只有一个人开发,那就没必要分接口和类了!

小编认为这位大佬写的这个很详细

接口与抽象

Java中抽象类与接口的详细说明的更多相关文章

  1. 转:二十一、详细解析Java中抽象类和接口的区别

    转:二十一.详细解析Java中抽象类和接口的区别 http://blog.csdn.net/liujun13579/article/details/7737670 在Java语言中, abstract ...

  2. 关于JAVA中抽象类和接口的区别辨析

    今天主要整理一下新学习的有关于Java中抽象类和接口的相关知识和个人理解. 1 抽象类 用来描述事物的一般状态和行为,然后在其子类中去实现这些状态和行为.也就是说,抽象类中的方法,需要在子类中进行重写 ...

  3. Java 中抽象类与接口的区别

    TypeScript 中的接口,有点类似抽象类的概念.Java 中抽象类属于包含属性与抽象行为,而接口通常只是抽象行为.抽象类可以实现模板模式. 参考 https://www.cnblogs.com/ ...

  4. 转载:详细解析Java中抽象类和接口的区别

    在Java语言中, abstract class 和interface 是支持抽象类定义的两种机制.正是由于这两种机制的存在,才赋予了Java强大的 面向对象能力.abstract class和int ...

  5. 详细解析Java中抽象类和接口的区别

    在Java语言中, abstract class 和interface 是支持抽象类定 义的两种机制.正是由于这两种机制的存在,才赋予了Java强大的 面向对象能力.abstract class和in ...

  6. 详细解析Java中抽象类和接口的区别(转)

    转自:http://dev.yesky.com/436/7581936.shtml 在Java语言中, abstract class 和interface 是支持抽象类定义的两种机制.正是由于这两种机 ...

  7. [转]详细解析Java中抽象类和接口的区别

    在Java语言中, abstract class 和interface 是支持抽象类定义的两种机制.正是由于这两种机制的存在,才赋予了Java强大的 面向对象能力.abstract class和int ...

  8. Java中抽象类和接口的区别

    转载自:http://dev.yesky.com/436/7581936.shtml 在Java语言中, abstract class 和interface 是支持抽象类定义的两种机制.正是由于这两种 ...

  9. java中抽象类与接口的区别

    1.abstract class 在 Java 语言中表示的是一种继承关系,一个类只能使用一次继承关系.但是,一个类却可以实现多个interface. 2.在abstract class 中可以有自己 ...

随机推荐

  1. 【题解】poj 3254 玉米田

    假如我们知道第i-1行的有x种放法,那么对于第i行的每一种放法都有x种,所以定义dp[i][j]表示第i行状态为j时的方法数,有转移方程:dp[i][j]=sum(dp[i-1][k]) k表示i-1 ...

  2. js 正则(部分)

    /** * 增加大于某个值的验证 */window.ParsleyValidator.addValidator( 'greater', function (value,greater) { if(is ...

  3. JS的IIFE

    1. 定义 IIFE: Immediately Invoked Function Expression,意为立即调用的函数表达式,也就是说,声明函数的同时立即调用这个函数. 首先我们要了解一般情况下什 ...

  4. 5.5 Go defer

    5.5 Go defer 程序开发中经常要创建资源(数据库初始化连接,文件句柄,锁等),在程序执行完毕都必须得释放资源,Go提供了defer(延时机制)更方便.更及时的释放资源. 1.内置关键字def ...

  5. vue项目中使用bpmn-流程图json属性转xml(七篇更新完成)

    内容概述 本系列“vue项目中使用bpmn-xxxx”分为七篇,均为自己使用过程中用到的实例,手工原创,目前陆续更新中.主要包括vue项目中bpmn使用实例.应用技巧.基本知识点总结和需要注意事项,具 ...

  6. 最香远程开发解决方案!手把手教你配置VS Code远程开发工具,工作效率提升N倍

    文章每周持续更新,原创不易,「三连」让更多人看到是对我最大的肯定.可以微信搜索公众号「 后端技术学堂 」第一时间阅读(一般比博客早更新一到两篇) 今天和大家分享远程开发工具,分享一下我平常是如何用 V ...

  7. kube-controller-manager反复重启解决

    背景 ​ 某环境,kube-controller-manager反复重启,尝试重建kube-controller-manager的pod,但是过一会问题复现. 如上图,kube-controller- ...

  8. mysql小白系列_13 Online DDL

    Online DDL: 一.FIC之前的添加删除二级索引: 1.首先创建临时表,定义目标新表的选项和索引 2.逐行拷贝数据到临时表 3.插入行时更新索引信息 4.数据全部被拷贝到新表后,删除旧表,re ...

  9. SpringBoot_自动装配

    SpringBoot SrpingBoot 给人的第一印象就是 简洁,易上手.它是自 Spring 而来为了简化我们开发的,而经历过了 Spring 中繁琐的配置文件,我确实很好奇它到底是怎么帮我们把 ...

  10. Gym101142G Gangsters in Central City

    题目链接:https://cn.vjudge.net/problem/Gym-101142G 知识点: DFS序.LCA 题目大意: 给定一棵有根树(根为 \(1\)).每次修改叶子节点会被染成黑色( ...