抽象类:

抽象类的基本概念:

在面向对象的概念中,所有的对象都是通过类来描述并创建的,但是有一种特殊的类,并不能用完整的信息来描述一个具体的对象,这样的类就是抽象类不能完整描述对象相关信息的方法,通常称为抽象方法,也就是说,抽象类中需要包含抽象方法。

例如:

几何图形中有三角形,圆形,矩形,多边形的我们通常称为形状,形状就是对各种具体几何图形的模糊化,抽象化的通称,但形状本身又不能归结于某一个具体的几何图形,假如说形状就是三角形,这样的定义显然与现实不符,形状都具有面积,但是不同具体形状的面积有不同的计算方法,如果形状不能具体化,那么面积就无法计算,如果将形状表现为抽象,那么面积就是其中的抽象方法。

抽象类一般作为父类,在抽象类中定义抽象方法,并交给抽象类的子类去实现抽象方法,也就是说在抽象类的各个子类中去定义完善某个具体对象的描述。

抽象方法和抽象类的定义:

抽象方法是一种“特殊”的方法,该方法只有方法的定义部分(只有方法头)而没有方法的实现部分(没有方法体),在访问权限和返回类型之间需要用abstract关键字进行修饰。

定义格式如下:

权限修饰符 abstract returntype 方法名([参数列表]);

注意:

1:抽象方法只有方法头部并以“;”结束,没有方法体,所以后面不能有"{}"

2:构造方法不能被定义为抽象方法。

3:抽象类在定义时需要在class前添加abstract关键字修饰,类体中至少包含一个抽象方法,其余内容和普通方法一样,也可以定义普通常量,普通方法等。

定义格式如下:

[权限修饰符] abstract class 类名称{成员属性;
常量;
构造方法([参数列表])//构造方法
{..........}
[权限修饰符] returntype 方法名([参数列表])//普通方法
{..........}
abstract returntype 方法名([参数列表])//抽象方法
{..........}
}

注意:

1:由于抽象类是需要被子类继承的,所以抽象类不能使用final关键字修饰。

2:抽象类中定义的抽象方法是要被子类覆盖的,所以抽象方法不能用final关键字修饰,而且抽象类的访问权限不能是private。

3:抽象方法不能被static关键字修饰,抽象方法必须是实例方法。

4:抽象类不能用new运算符创建它的对象。

抽象类本身不能实例化,抽象类必须要有子类来继承它,否则抽象类就失去了存在的意义。

由于抽象类的子类实现了抽象类的抽象方法,从多态的角度讲,一般通常都是定义抽象类的引用指向抽象类子类的实例,自动完成上转型,因此,使用抽象类是对象多态性的一个很好的体现。

举例:

//Animal是抽象类[父类]  Sheep是抽象类的子类[父类]
//通过上转型方式定义抽象类的子类对象Aninmal sheep1=new Sheep();

抽象类的应用:

关于抽象类的应用,这里我使用我们的实验中的一个进行作为例子:

-----顾客就餐实验:

首先我们先对实验内容进行分析,根据上图,很清楚的表明了Restaurant为继承类,也就是所谓的父类,其中它包含了3个抽象方法和一个普通方法,但这些方法的数量并不是一成不变的,我们可根据自己的理解进行调整。

对于问候或者加工这种无论是什么餐厅都是相同的,那么我们就将其写在父类中,而对于菜品的种类和点菜过程这种应写在不同的子类中。

代码如下所示;

package Restuarant;abstract class restuarant {//实验内容要求的抽象类public abstract  void pay();public abstract   void order();public abstract  void repast();public void message(){//新增普通方法System.out.println("顾客用餐完毕,请通知服务人员尽快打扫对应的餐桌!");}public void process(){//实验内容要求的普通类System.out.println("您所点的菜品正在准备,请耐心等待!");System.out.println("----------------");System.out.println("菜品制作完成");}}

上文我们说过,抽象类本身不能实例化,抽象类必须要有子类来继承它,否则抽象类就失去了存在的意义,那么接下来我们就创建它的子类。

首先子类必须重写父类所有的抽象方法,当然子类也可以创建属于自己的变量和方法。

package Restuarant;import java.util.Scanner;public class Pizza extends restuarant{double A=29.9;double B=19.7;double C=49.8;double D=9.9;double sum=0.0;public double getSum() {return sum;}public void setSum(double sum) {this.sum = sum;}public double getD() {return D;}public void setD(double d) {D = d;}public double getC() {return C;}public void setC(double c) {C = c;}public double getB() {return B;}public void setB(double b) {B = b;}public double getA() {return A;}public void setA(double a) {A = a;}public void show_pizza() {//子类特有的方法System.out.println("本店菜品如下:");System.out.println("1-双人套餐:"+A+",2-单人套餐:"+B+",3-全家桶:"+C+",4-儿童套餐:"+D);}
//重写父类的@Overridepublic void repast() {System.out.println("----------------");System.out.println("顾客正在2号餐厅吃饭......");}@Overridepublic void pay() {System.out.println("请点击你需要的菜品号:结束点单请输入0!");Scanner in = new Scanner(System.in);int[] Q=new int[3];for(int i=0;i<4;i++){Q[i]=in.nextInt();if(Q[i]==0)break;if(Q[i]==1)sum+=A;else if(Q[i]==2)sum+=B;else if(Q[i]==3)sum+=C;else if(Q[i]==4)sum+=D;}}@Overridepublic void order() {System.out.println("您需要支付的金额为:"+sum);System.out.println("等待用户支付......");System.out.println("----------------");System.out.println("支付成功,祝您用餐愉快!");}}

其他两个子类均是如此,根据子类不同的特点将其就行改写和完善,这里就不过多赘述了。

package Restuarant;
import java.util.Scanner;
public class KFC extends restuarant{double a=15.9;double b=7.9;double c=4.9;double sum=0.0;public double getSum() {return sum;}public void setSum(double sum) {this.sum = sum;}public double getA() {return a;}public void setA(double a) {this.a = a;}public double getB() {return b;}public void setB(double b) {this.b = b;}public double getC() {return c;}public void setC(double c) {this.c = c;}public void show_KFC() {System.out.println("本店菜品如下:");System.out.println("1-炸鸡:"+a+",2-爆米花:"+b+",3-可乐:"+c);}@Overridepublic void order() {System.out.println("请点击你需要的菜品号:结束点单请输入0!");Scanner in = new Scanner(System.in);int[] B=new int[3];for(int i=0;i<3;i++){B[i]=in.nextInt();if(B[i]==0)break;if(B[i]==1)sum+=a;else if(B[i]==2)sum+=b;else if(B[i]==3)sum+=c;}}@Overridepublic void pay() {System.out.println("您需要支付的金额为:"+sum);System.out.println("等待用户支付......");System.out.println("----------------");System.out.println("支付成功,祝您用餐愉快!");}@Overridepublic void repast() {System.out.println("----------------");System.out.println("顾客正在1号餐厅吃饭......");}
}
package Restuarant;import java.util.Scanner;public class breakfast extends restuarant{double noodles=8;double dumplings=7.9;double rices=4.9;double Casserole=13;double sum=0.0;public double getNoodles() {return noodles;}public void setNoodles(double noodles) {this.noodles = noodles;}public double getDumplings() {return dumplings;}public void setDumplings(double dumplings) {this.dumplings = dumplings;}public double getRices() {return rices;}public void setRices(double rices) {this.rices = rices;}public double getCasserole() {return Casserole;}public void setCasserole(double casserole) {Casserole = casserole;}public double getSum() {return sum;}public void setSum(double sum) {this.sum = sum;}public void show_breakfast() {System.out.println("本店菜品如下:");System.out.println("1-面条:"+noodles+",2-饺子:"+dumplings+",3-米饭:"+rices+",4-砂锅"+Casserole);}@Overridepublic void pay() {System.out.println("请点击你需要的菜品号:结束点单请输入0!");Scanner in = new Scanner(System.in);int[] Q=new int[3];for(int i=0;i<4;i++){Q[i]=in.nextInt();if(Q[i]==0)break;if(Q[i]==1)sum+=noodles;else if(Q[i]==2)sum+=dumplings;else if(Q[i]==3)sum+=rices;else if(Q[i]==4)sum+=Casserole;}}@Overridepublic void order() {System.out.println("您需要支付的金额为:"+sum);System.out.println("等待用户支付......");System.out.println("----------------");System.out.println("支付成功,祝您用餐愉快!");}@Overridepublic void repast() {System.out.println("----------------");System.out.println("顾客正在3号餐厅吃饭......");}
}
package Restuarant;import java.util.Scanner;public class Test {public static void main(String[]args){System.out.println("请输入你想去的餐厅:");Scanner in = new Scanner(System.in);int select=in.nextInt();if(select==1){KFC kfcs=new KFC();kfcs.show_KFC();kfcs.order();kfcs.pay();kfcs.process();kfcs.repast();kfcs.message();}if(select==2){Pizza pizza=new Pizza();pizza.show_pizza();pizza.order();pizza.pay();pizza.process();pizza.repast();pizza.message();}if(select==3){breakfast breakfasts=new breakfast();breakfasts.show_breakfast();breakfasts.order();breakfasts.pay();breakfasts.process();breakfasts.repast();breakfasts.message();}}
}

输出:

请输入你想去的餐厅:
3
本店菜品如下:
1-面条:8.0,2-饺子:7.9,3-米饭:4.9,4-砂锅13.0
您需要支付的金额为:0.0
等待用户支付......
----------------
支付成功,祝您用餐愉快!
请点击你需要的菜品号:结束点单请输入0!
3
0
您所点的菜品正在准备,请耐心等待!
----------------
菜品制作完成
----------------
顾客正在3号餐厅吃饭......
顾客用餐完毕,请通知服务人员尽快打扫对应的餐桌!

接口:

接口的基本概念:

现实世界的接口通常是指两个不同物体之间相互交互所必须通过的一个中介,没有,这个中介,两者就无法进行交互,我们把这个中介,称为,接口,例如门窗户,楼道插孔电梯间等,在软件世界中所提到的接口有狭义和广义之分的,狭义的接口是指某个程序设计语言所提供的API广义的接口是指人与软件交互的图形界面,通过这个图形界面,人们才能使用此软件JAVA中的接口是一种特殊的类接口中只能包含常量和抽象方法属于符合数据类型,是狭义的接口

接口的作用:

通过之前的学习,我们了解到,JAVA是纯面向对象的程序设计语言,为了避免多继承产生的二义性,在java中类的继承只能实现单继承,不能实现多继承,但多继承也有许多优点,她允许一个子类可以继承多个父类的属性和方法,使得子类能够具有多个父类的特性,但是java并没有因为只允许单继承而抛弃多继承带来的便利为了结合多继承的优点,又不与单继承冲突就提供了接口这个新技术来实现多继承的效果通过使用接口可以体现面向对象中的多态机制。

接口的定义和实现:

Java使用关键字interface定义接口,接口的定义和类很相似,分为接口声明和接口体两个部分。

定义格式:

[public] interface 接口名[extends interface1,interface2, interface3,interface4........]{//interface1,interface2, interface3,interface4为接口名
double E=2.178;//常量的定义
void dosomething(int i,double x);//抽象方法的定义
}

接口中能够定义的成员只有常量和抽象方法两种(或者两选一),不能包含构造方法**,接口中的常量默认是public访问权限,并且是静态的,所以常量定义前的public static final关键字可以省略不写,接口中抽象方法的访问权限默认也是public,所以抽象方法前面的public abstract关键字也可以省略不写,接口不存在类的单继承限制,一个接口可以继承多个接口,多个接口名之间用逗号隔开。**

例如:

interface myinterface extends interface1,interface2, interface3,interface4........{//interface1,interface2, interface3,interface4为接口名
..............
}

注意:

<1>接口的继承不存在最高层,也就是不存在最顶层的接口,而类的继承存在最高层,最顶层是java.lang.Object.

<2>接口的实现需要交给类来完成实现接口的类继承了接口中的常量并且要重写接口中所有的抽象方法,一个类需要在声明中使用关键字implements表示要实现的一个或多个接口,如果一个类要实现多个接口,多个接口名字之间需要通过逗号隔开。

例如:

class A implements Interface1,Interface2

实现类要给出接口中抽象方法的具体行为,如果一个类只重写了接口中的部分抽象方法,相当于这个类还继承有接口中的抽象方法,那么这个类就不能称为普通类,需要定义为抽象类。

假如上述例子中的A类并没有完全实现接口 Interface1,Interface2和中的所有抽象方法,那么它就必须定义为abstract类:

如下所示:

abstract class A implements Interface1,Interface2

注意:

<1>接口的实现类重写接口中定义的抽象方法时,需要显式添加public访问权限(否则无法实现覆盖),去掉abstract关键字,同时给出方法体部分。

<2>如果父类实现了某个接口,那么子类也就自然实现了这个接口,子类不必再显式地使用关键字implements声明这个接口。

抽象类和接口的应用:

关于抽象类和接口结合的应用,这里我还是使用我们的实验中的一个进行作为例子:

-----模拟物流的过程

首先我们还是对实验内容进行分析,Transportion为抽象类,也就是所谓的父类,其中包含实验所需的变量,物流号,具体的交通工具名称等,还包含一个抽象方法----运输方法,那么子类需要实现将这个抽象的运输方法具体化,也就是说运输方法可以是汽车,飞机,卡车等。

代码如下:

package transport1;abstract class Transportion {String model;String  code;String admin;String number;public  abstract void transportion();public String getModel() {return model;}public void setModel(String model) {this.model = model;}public String getNumber() {return code;}public void setNumber(String number) {this.code = number;}public String getAdmin() {return admin;}public void setAdmin(String admin) {this.admin = admin;}}

—创建子类

和上述餐厅点餐实例的子类基本相同,唯一不同的地方就是该子类不仅继承了一个父类还实现了一个接口carable,那么该子类也需要对接口中所有的抽象方法进行重写。

package transport1;public class Car extends Transportion implements carable{@Overridepublic void transportion() {// TODO Auto-generated method stubSystem.out.println(admin+"开着"+model+"在拉货物");}public Car(String admin,String model,String number) {this.admin=admin;this.model=model;this.number=number;}@Overridepublic void upkeep() {System.out.println("汽车保养完成!");}
}

–货物运输类

和上述餐厅点餐实例的子类基本相同,这里不过多赘述!

package transport1;public class send_task extends Transportion {String number;double goodweight;String admin;public send_task(String number,double goodweight,String admin) {this.number = number;this.goodweight=goodweight;this.admin=admin;}@Overridepublic void transportion() {System.out.println("编号为:"+number+"的货物即将开始运输!");}public void sendBefor(){//送货前System.out.println("订单开始处理,仓库验货中......");System.out.println("货物重量为"+goodweight);System.out.println("货物检验完毕!");System.out.println("货物填装完毕 !");System.out.println("已通知运货人");System.out.println("快递单号:"+number);System.out.println("=======================");}public void sendAfter(String name,String model){//送货后System.out.println(admin+"已将编号为"+number+"的"+model+"货车归还");}public void send(String name,String model){//送货中System.out.println(admin+"正在驾驶编号为"+number+"的"+model+"发送货物");System.out.println("货物运输中....");}}

—定义类Martphone实现接口GPS,也就是实现货物的定位功能!

package transport1;public class Martphone implements GPS{@Overridepublic void showcoordinate() {System.out.println("当前货物状态为:北京----->石家庄");System.out.println("=======================");}}
package transport1;public interface GPS {public void showcoordinate();}

—定义保养功能,由于在现实生活中某些交通工具需要定期进行保养,而有的则不需要。

package transport1;public interface carable  {public void upkeep();}

–测试类

package transport1;public class text {public static void main(String[]args) {Car car=new Car("张三","汽车","5");car.transportion();send_task tasks=new send_task("EMS1234",23.5,"张三");tasks.sendBefor();tasks.transportion();tasks.send("张三","汽车");Martphone phone=new Martphone();phone.showcoordinate();tasks.sendAfter("张三","汽车");}
}

输出:

张三开着汽车在拉货物
订单开始处理,仓库验货中......
货物重量为23.5
货物检验完毕!
货物填装完毕 !
已通知运货人
快递单号:EMS1234
=======================
编号为:EMS1234的货物即将开始运输!
张三正在驾驶编号为EMS1234的汽车发送货物
货物运输中....
当前货物状态为:北京----->石家庄
=======================
张三已将编号为EMS1234的汽车货车归还

接口和抽象类的比较:

相同点:

<1>抽象类和接口都包含抽象方法,抽象类需要被子类继承,子类去实现抽象类中定义的抽象方法,接口需要被类去实现,实现接口的类需要实现接口中定义的所有抽象方法。

<2>抽象类和接口都不能通过new关键字来创建自己的对象。

<3>抽象类和接口都是引用数据类型,可以声明抽象类和接口类型的引用变量,并将子类的对象实例赋给抽象类和接口变量,也就是说抽象类和接口都可以按照上转型方式去创建对象。

不同点:

那么它们究竟如何进行选择呢?

如果说某个问题需要使用继承才能更好的解决,例如,子类除了需要重写父类的抽象方法,还需要从父类继承一些变量或者一些中的普通方法,那么就可以使用抽象类,但是如果某个问题不需要继承,只是需要若干个类给出某些重要的抽象方法的实现逻辑,此时便可以考虑接口。

Java---抽象类和接口相关推荐

  1. java定义一个door的类_再探Java抽象类与接口的设计理念差异

    原文:http://blog.csdn.net/sunboard/article/details/3831823 1.概述 一个软件设计的好坏,我想很大程度上取决于它的整体架构,而这个整体架构其实就是 ...

  2. 没有体现JAVA接口功能_深入浅出分析Java抽象类和接口【功能,定义,用法,区别】...

    本文实例讲述了Java抽象类和接口.分享给大家供大家参考,具体如下: 对于OOP编程来说,抽象是它一大特征之一.在Java中,可以通过两种形式来体现OOP的抽象:抽象类和接口. 这两者有相似之处也有很 ...

  3. JAVA抽象类和接口的深入探讨

    Java 语言中,抽象类(abstract class) 和接口(interface) 是抽象思想的两种体现形式.初学者很容易把这两者搞混,所以Java面试中考抽象类和接口的区别的面试题也常有出现的. ...

  4. java 抽象类和接口2--什么时候用接口什么时候用抽象类

    java 抽象类和接口1–基本概念 https://blog.csdn.net/qq_26296197/article/details/81315685 从生活的角度看 把编程映射会日常生活进行对照, ...

  5. JAVA学习经验--总结JAVA抽象类和接口

    * --总结JAVA抽象类和接口  * 1.抽象类:  *             1>抽象类可以修饰方法,修饰类,但不能修饰属性,不能被实例化  *             2>抽象类可 ...

  6. java接口vm和dto的区别_第十八节:详解Java抽象类和接口的区别

    前言 对于面向对象编程来说,抽象是它的特征之一. 在Java中,实现抽象的机制分两种,一为抽象类,二为接口. 抽象类为abstract class,接口为Interface. 今天来学习一下Java中 ...

  7. JAVA抽象类和接口类的区别

    JAVA抽象类和接口类的区别 1.声明方式不同.抽象类为abstract class,接口类为interface. 2.继承抽象类关键字为extends,实现接口关键字为implements. 3.继 ...

  8. 再探Java抽象类与接口的设计理念差异

    Java抽象类与接口都可以实现功能与实现的分离,都对多态提供了很好的支持,那么我们什么时候应该使用抽象类或接口呢?在以前的一篇文章初探Java抽象类与接口中谈到了他们语法的区别,在博客通过模板方法模式 ...

  9. jdk1.8中,java 抽象类和接口的区别

    抽象类 特点: 1.抽象类中可以构造方法 2.抽象类中可以存在普通属性,方法,静态属性和方法. 3.抽象类中可以存在抽象方法. 4.如果一个类中有一个抽象方法,那么当前类一定是抽象类:抽象类中不一定有 ...

  10. JAVA抽象类和接口的区别【附经典分析用例Door】

    这篇文章对抽象类和接口说的很详细,希望对大家有所帮助. abstract class和interface是Java语言中对于抽象类定义进行支持的两种机制,正是由于这两种机制的存在,才赋予了Java强大 ...

最新文章

  1. DataGrid/DataList
  2. DPI — Application Assurance — Overview
  3. mysql给数据库重命令_mysql 重命令数据库
  4. python 中super方法的调用
  5. 在阿里云里申请免费Https证书SSL
  6. Spark _16 _SparkUIMaster HA
  7. 小度智能音箱维修点_小度智能音箱APP下载
  8. mybatis源码阅读(六) ---StatementHandler了解一下
  9. iap如何初始化_IAP在线升级模块详细设计说明
  10. [转载] python中pprint模块详解——print()和pprint()两者的区别
  11. 360的编码html怎么写,html5之meta charset网页字符编码简写
  12. 在webconfig中写好连接后,在程序中如何调用?
  13. C语言求解鸡兔同笼问题
  14. 【深度】美俄机器人集群军事作战应用研究现状!三大关键技术体系分析
  15. 炒币玩波段为什么一定要设置止损止盈?
  16. 苹果IOS 10.0.2屏蔽垃圾短信
  17. html如何把素材做成按钮,html botton html submit按钮表单控件与CSS美化
  18. 问题-某个程序改了ICO图标后编译后还是显示老图标?
  19. 最常用英语口语200句
  20. android 照片墙程序,Android照片墙应用

热门文章

  1. 暗影精灵8 双系统 ubantu20.04(无线网卡为Intel WIFI6E AX211)
  2. 按键精灵_50多个特殊文件夹路径的获取方法
  3. PHP 编写学生成绩
  4. 非暴力沟通:沟通场景
  5. php导出数据到csv文件,php导出CSV文件代码 PHP导出数据到CSV 如何排版
  6. 二分查找—林克的蛋糕
  7. vue-router动态路由设置自定义首页
  8. 机器学习系列(18)_Kaggle债务违约预测冠军经验分享
  9. 我的世界linux联机游戏,MineCraft 我的世界 – PC 端联机服务器搭建 ( Linux )
  10. 前端开发——图标返回顶部功能