抽象类和抽象方法

定义

  • 抽象方法和抽象类都必须被abstract关键字修饰。
  • 抽象——abstract,抽象类的方法不一定是抽象的,但抽象方法出现的类一定是抽象类。
//抽象方法,没有方法体(即没有{}),只有声明
abstract void f();
  • 最重要的是:抽象类,抽象既不是真的,所以,抽象类不可以实例化。但可以通过子类的实例化来使用
/**
* @author yhy
* 用来完成9.2的练习
* 验证抽象类与抽象方法的使用
*/
public class YanZheng {
public static void main(String[] args) {
// 不能被实例化,抽象类,会报错
// ChouXiang chouxi = new ChouXiang() ;
// 可以实例child类
// 即通过继承其子类来实现不能继承抽象类
Child test = new Child();
}
}
abstract class AbstractChouXiang{
/**
* 构造函数
*/
AbstractChouXiang() {
}
/**
* 定义一个抽象类的抽象方法
*/
abstract void chouxiang();
}
class Child extends AbstractChouXiang{
Child(){
System.out.println("实例时候就打印出来");
} /**
* 注意这里不是abstract就不要讲方法定义为abstract
*/
@Override
void chouxiang(){
System.out.println("继承抽象类"); }
}
  • 子类可以不是抽象类,但要实现抽象父类中的所有抽象方法,否则必须定义为abstract类型。(下面的代码中,我将其子类的重写方法注释掉之后,就会报错must be declared abstract or implentment abstract method)

与普通类的区别以及注意点:

  • 抽象类也是可以与普通类那样,可以直接extends,区别在于抽象类不能直接实例化,可以通过实例化其子类,通过子类重写方法实现等——设置抽象方法就是让子类来实现的,否则毫无意义。

  • 与普通方法的区别

    抽象方法和空方法体的方法不是同一个概念。例如,public abstract void test();是一个抽象方法,它根本没方法体,即方法定义后面没有一对花括号;但public void test(){}方法是一个普通方法,它已经定义了方法体,只是方法体为空,即它的方法体什么也不做,因此这个方法不可使用abstract来修饰。——疯狂的Java讲义

  • abstract不能用于修饰Field,不能用于修饰局部变量,即没有抽象变量、没有抽象Field等说法;abstract也不能用于修饰构造器,没有抽象构造器,抽象类里定义的构造器只能是普通构造器

抽象类的作用

  • 《thinking in java》

    • 抽象类是普通的类与接口之间的一种中庸之道。

    • 抽象方法、抽象类可以使类的抽象性明确起来,告诉用户和编译器怎么使用它们;

    • 同时,抽象类是很好的重构工具,在后期的工作中,可以实现重用性。

  • 体现一种模板的效果,从一群相似的子类提炼出一个抽象类的感觉一样,提供了一种规范,子类可以在其原来的基础上进行扩展。

  • 抽象父类可以只定义需要使用的某些方法,把不能实现的部分抽象成抽象方法,就是一中留给下一代去实现,一开始没有能力去实现,那可就给厉害的人去做,留给其子类去实现。

接口

定义

  • 特殊的“抽象类”——接口(interface):比抽象类更加抽象的是接口,在接口中所有的方法都是抽象的。就不能像上面的抽象类一样还可以有普通方法。
//省略public就变为默认级别,只能在当前包所访问
public interface Figure {
//接口中静态成员变量
String name = "几何图形";//省略public static final
// 绘制几何图形方法
void onDraw(); //省略public 这里是抽象方法
}
  • Java中可以implements多个接口,多继承的含义便是接入多个接口(继承只能单继承)
  • 一个类可以实现一个或多个接口,继承使用extends关键字(但接口只能继承接口),实现则使用implements关键字。

示例

  • JieKou.java
import java.text.SimpleDateFormat;

/**
* @author yhy
* 这个是实现接口定义的代码,在其它地方去调用
* 这里的接口不用public的话,其它的包就访问不了
*/
public interface JieKou {
// 定义了两个常量
/**
* 这里定义一个df变量来获取当前时间
*/
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
String AUTHOR = "yhycoder";
/**
* 定义一个接口的方法
* 这里的public是多余的,在接口里面是自动为public
*/
/*public*/ void print();
}
  • 使用接口的Java代码
//访问了其它包的接口,就是下面这个地址
import music.daima.ebook.JieKou;
import java.util.Date; public class UseInterfaces {
public static void main(String[] args) {
//实例化using类,实现查看代码的运行情况
Using Shuchu = new Using();
Shuchu.print(); }
} /**
* 这里是接口继承接口
*/
interface Jiekou2 extends JieKou{
String num = "接口2";
} /**
* 这里是Using类实现了JieKou和Jiekou2接口,逗号隔开
*/
class Using implements JieKou,Jiekou2 {
/**
* 重写了方法,调用接口定义的常量
*/
@Override
public void print() {
System.out.println(AUTHOR+"在新的包里面使用接口的时间:"+df.format(new Date())+" 同时还有"+num);
}
}

注意

  1. 接口与抽象类一样都不能被实例化
  2. 实现接口时接口中原有的抽象方法在实现类中必须实现。默认方法可以根据需要有选择实现(覆盖)。静态方法不需要实现,实现类中不能拥有接口中的静态方法。(Java 8之后)
//InterfaceA.java文件,定义一个接口
public interface InterfaceA {
//抽象方法
void methodA();
String methodB();
// 默认方法
default int methodC() {
return "6666";
}
// 默认方法
default String methodD() {
return "这是默认方法";
}
// 静态方法
static double methodE() {
return 0.0;
}
}

实现接口代码

import xxxx.InterfaceA;
public class ABC implements InterfaceA {
//重写
@Override
public void methodA() {
}
@Override
public String methodB() {
return "实现methodB方法...";
}
//重写覆盖,根据自己的需要来。
@Override
public int methodC() {
return 500;
}
}
//实现类中不能有接口中的静态方法,最后一行
public class HelloWorld {
public static void main(String[] args) {
//声明接口类型,对象是实现类,发生多态
InterfaceA abc = new ABC();
// 访问实现类methodB方法
System.out.println(abc.methodB());
// 访问默认方法methodC
System.out.println(abc.methodC());
// 访问默认方法methodD
System.out.println(abc.methodD());
// 访问InterfaceA静态方法methodE,这里不能通过实现类去使用接口的静态方法,只能通过接口名调用
System.out.println(InterfaceA.methodE());
}
}

作用

  1. 规范,在分配不同人的任务时,接口就像是总纲一样,告诉大家去实现哪些功能模块等。(命名规范都有限制到)

最后:接口与抽象类的异同

不同

  • 接口interface,实现接口则使用implements;抽象类abstract

  • 抽象类可以有普通方法。Java 8 之前接口中只有抽象方法,而 Java 8 之后接口中也可以声明具体方法,具体方法通过声明默认方法实现。

  • 接口可以继承多个,而抽象类不可以。

  • 和类继承相似,子接口扩展某个父接口,将会获得父接口里定义的所有抽象方法、常量Field、内部类和枚举类定义。

  • 实现父接口的所有:一个类实现了一个或多个接口之后,这个类必须完全实现这些接口里所定义的全部抽象方法(也就是重写这些抽象方法);否则,该类将保留从父接口那里继承到的抽象方法,该类也必须定义成抽象类。

  • 接口定义的是一种规范,因此接口里不能包含构造器和初始化块定义。接口里可以包含Field(只能是常量)、方法(只能是抽象实例方法)、内部类(包括内部接口、枚举)定义。但抽象类与普通类一样,可以有构造器,初始化模块等。

  • 接口只有常量——接口中不能有实例成员变量,接口所声明的成员变量全部是静态常量,即便是变量不加 public static final 修饰符也是静态常量。抽象类与普通类一样各种形式的成员变量都可以声明。

相同

  • 都不能直接实例化来使用。
  • 接口和抽象类都可以包含抽象方法,实现接口或继承抽象类的普通子类都必须实现这些抽象方法。

使用场景

  • 想要多重继承的时候——接口(功能性强,规范性)

  • 想要底层基础功能模块不断改变——抽象类(模板设计)

感谢

才疏学浅,不对的地方多多指教!

借鉴

博客园的小伙伴

也是园内小伙伴

论Java中的抽象类与接口的更多相关文章

  1. Java 中,抽象类与接口之间有什么不同?

    Java 中,抽象类和接口有很多不同之处,但是最重要的一个是 Java 中限制一个 类只能继承一个类,但是可以实现多个接口.抽象类可以很好的定义一个家族类 的默认行为,而接口能更好的定义类型,有助于后 ...

  2. java中的抽象类和接口

    抽象类和接口本身让面向对象真正实现,一个好的系统可以让抽象类或者接口实现多次复用,如果出现了集成具体类那么肯定是有问题的. 抽象类和接口很相似,很多时候好像功能可以混用,java设计者赋予了很多不一样 ...

  3. Java 中的抽象类及接口

    抽象类使用 abstract 关键字修饰,该类即为抽象类. 抽象类的作用: 1.某些情况下,父类约束子类必须包含哪些方法,但不知道子类如何去实现这些方法. 2.可以从多个具有相同特征的类中抽象出一个抽 ...

  4. JAVA中的抽象类与接口

    抽象类 abstract class 包含抽象方法的类,叫抽象类.而抽象的概念就是抽象出共同属性:成员变量和方法.所以抽象类可以有private等多种权限的成员变量和非abstract的成员方法.当然 ...

  5. 辨异 —— Java 中的抽象类和接口

    接口优于抽象类.-- <Effective Java>(Item 18) 0. 语法区别 抽象类允许给出某些方法的实现,接口不允许: 为了实现由抽象类定义的类型(type),类必须成为抽象 ...

  6. java基础(四)-----抽象类与接口

    抽象类与接口是java语言中对抽象概念进行定义的两种机制,正是由于他们的存在才赋予java强大的面向对象的能力.他们两者之间对抽象概念的支持有很大的相似,甚至可以互换,但是也有区别. 一.抽象类 我们 ...

  7. Java学习笔记二十七:Java中的抽象类

    Java中的抽象类 一:Java抽象类: 在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就 ...

  8. Java基础之抽象类与接口

    Java基础之抽象类与接口 对于面向对象编程来说,抽象是它的一大特征之一.在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类.这两者有太多相似的地方,又有太多不同的地方.很多人在初学的时候 ...

  9. C++中的抽象类和接口

    1,在 C++ 语言中,并不直接支持面向对象中的抽象类和接口概念,但是 C++ 语言 却可以间接实现这些概念: 2,什么是抽象类: 1,面向对象中的抽象(其实就是分类)概念: 1,在进行面向对象分析时 ...

随机推荐

  1. Oracle - @和@@、&与&& 的区别

    2018-01-15 15:36:17 袭冷 阅读数 4783更多 分类专栏: DB   版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接 ...

  2. supersockets接收过滤器(ReceiveFilter)

    接收过滤器(ReceiveFilter)用于将接收到的二进制数据转化成请求实例(RequestInfo). 实现一个接收过滤器(ReceiveFilter), 你需要实现接口 IReceiveFilt ...

  3. 条件随机场(CRF) - 3 - 概率计算问题

    声明: 1,本篇为个人对<2012.李航.统计学习方法.pdf>的学习总结,不得用作商用,欢迎转载,但请注明出处(即:本帖地址). 2,由于本人在学习初始时有很多数学知识都已忘记,所以为了 ...

  4. 洛谷P3150 pb的游戏(1)题解 博弈论入门

    题目链接:https://www.luogu.org/problem/P3150 这道题目是博弈论的入门题. 我们以 必胜态 和 必败态 来讲解这个问题. 首先,下面的图片演示了前8个数的必胜态和必败 ...

  5. Python--day41--线程锁

    1,死锁 死锁代码示例: import time from threading import Lock, Thread noodle_lock = Lock() fork_lock = Lock() ...

  6. C# double 好用的扩展

    在很多代码需要使用数学计算,在用到 double 很难直接判断一个值是 0 或者 1 ,判断两个值相等. 本文提供一个数学扩展,让大家可以简单使用到 double 判断 在开始看本文之前,希望大家是知 ...

  7. ASP.NET MVC 实现页落网资源分享网站+充值管理+后台管理(10)之素材管理

    源码下载地址:http://www.yealuo.com/Sccnn/Detail?KeyValue=c891ffae-7441-4afb-9a75-c5fe000e3d1c 素材管理模块也是我们这个 ...

  8. 树莓派4安装net core3.0环境

    树莓派4官方系统是32系统,所以需要安装arm32版本的net core sk和runtime 1,首先创建一个文件夹 dotnet-arm32 sudo mkdir dotnet arm32 2,下 ...

  9. Cisco DNA-C POC环境配置

    Step1:在DNA-C上创建Site,本例创建Global->China->WangJiang->20 F如下图: Step2:配置fusion区域的AAA和NTP等信息,如下图: ...

  10. Android多媒体框架

    Android系统的多媒体架构图 OpenMax做编解码作用(codec),从上到下依次是AL(应用层,在多媒体中间件和应用程序之间提供一个标准化接口).IL(集成层,解码编码器).DL(开发层,供应 ...