抽象类

在第16节继承中,有父类 People

  1. People people=new People();
  2. people.sayHi();

实例化People是没有意义的,因为“人”是一个抽象的概念。

怎么才能避免父类的实例化呢?使用 abstract 关键字修饰类(抽象类)。

抽象父类

  1. public abstract class People {
  2. private String name;
  3. public People(String name) {
  4. super();
  5. this.name = name;
  6. }
  7. //人类共有方法 哭
  8. public void cry() {
  9. System.out.println("呜呜");
  10. }
  11. //抽象方法 不做具体实现
  12. public abstract void sayHi();
  13. public String getName() {
  14. return name;
  15. }
  16. public void setName(String name) {
  17. this.name = name;
  18. }
  19. }

子类:Chinese.java

  1. //中国人
  2. public class Chinese extends People{
  3. public Chinese(String name) {
  4. super(name);
  5. }
  6. //必须实现
  7. @Override
  8. public void sayHi() {
  9. System.out.println(this.getName()+":你好!");
  10. }
  11. }

子类:Britisher.java

  1. //英国人
  2. public class Britisher extends People{
  3. public Britisher(String name) {
  4. super(name);
  5. }
  6. @Override
  7. public void sayHi() {
  8. System.out.println(this.getName()+":Hello!");
  9. }
  10. }

测试类

  1. public class TestPeople {
  2. public static void main(String[] args) {
  3. //People people=new People("张三");//去掉注释试试
  4. People chinese=new Chinese("张三");
  5. chinese.sayHi();
  6. People britisher=new Britisher("John");
  7. britisher.sayHi();
  8. }
  9. }

被关键字 abstract 修饰的类是抽象类,抽象类不能实例化

被关键字 abstract 修饰的方法是抽象方法,抽象方法没有方法体

抽象方法必须在抽象类里

抽象方法必须在子类中被实现,除非子类是抽象类

抽象方法没有方法体

public abstract void sayHi();

注意:被 abstract 修饰后不能使用 final 修饰!

接口

如何实现防盗门这个类?门有“开”和“关”的功能,锁有“上锁”和“开锁”的功能,将门和锁分别定义为抽象类。但是防盗门可以继承门的同时又继承锁吗?不能,防盗门不是锁,不符合 is a 的关系而且Java只支持单继承。

接口的语法

  1. public interface MyInterface {
  2. public abstract void foo();
  3. }

接口可以认为是纯粹的抽象类

接口中的方法都是抽象方法 (public abstract)

接口不可以被实例化

实现类必须实现接口中的所有方法

接口中的变量都是静态常量

接口之间可以互相继承(extedns),类只能实现接口(implements)

一个类可以继承一个父类,实现多个接口

演示接口的继承及实现接口

父接口:A.java

  1. public interface A {
  2. void methodA();
  3. }

子接口:B.java

  1. public interface B extends A{
  2. void methodB();
  3. }

接口的实现类:C.java

  1. public class C implements B{
  2. @Override
  3. public void methodA() {
  4. }
  5. @Override
  6. public void methodB() {
  7. }
  8. }

接口表示能力

面向接口编程时,关心实现类有何能力,而不关心实现细节。面向接口的约定而不考虑接口的具体实现。

在鸟类中,白鹭可以飞,鸵鸟不能飞,所以在这里飞是一种能力,下面看一下代码的设计。

飞行接口:Fly.java

  1. //表示飞行能力
  2. public interface Fly {
  3. /**
  4. * 飞行
  5. */
  6. public abstract void fly();
  7. }

游泳接口:Swim.java

  1. //表示游泳能力
  2. public interface Swim {
  3. public abstract void swim();
  4. }

鸟类:Bird.java

  1. //抽象鸟类 重用代码
  2. public abstract class Bird {
  3. /**
  4. * 下蛋
  5. */
  6. public void layEggs() {
  7. System.out.println("产出一枚蛋");
  8. }
  9. }

白鹭类:Egret.java

  1. //白鹭类
  2. public class Egret extends Bird implements Fly,Swim{
  3. @Override
  4. public void fly() {
  5. System.out.println("使劲煽动翅膀后起飞");
  6. }
  7. @Override
  8. public void swim() {
  9. System.out.println("漂在了水面上,轻松的游来游去");
  10. }
  11. }

鸵鸟类:Ostrich.java

  1. //鸵鸟类
  2. public class Ostrich extends Bird implements Swim{
  3. @Override
  4. public void swim() {
  5. System.out.println("漂在了水面了,开始游动");
  6. }
  7. }

测试类

  1. public class TestBird {
  2. public static void main(String[] args) {
  3. Egret egret=new Egret();
  4. egret.swim();
  5. egret.fly();
  6. Ostrich ostrich=new Ostrich();
  7. ostrich.swim();
  8. }
  9. }

接口表示约定

在生活中,我们使用的插座,规定了两个接头剪得额定电压、两个接头间的距离、接头的形状。

在代码中约定体现在接口名称和注释上

下面使用面向接口编程实现一台计算机的组装,计算机的组成部分有:CPU、硬盘、内存。

先创建 CPU、硬盘、内存接口

  1. package computer;
  2. /**
  3. * CPU 接口
  4. * @author Jack
  5. *
  6. */
  7. public interface CPU {
  8. /**
  9. * 获取CPU品牌
  10. * @return
  11. */
  12. String getBrand();
  13. /**
  14. * 获取CPU主频
  15. * @return
  16. */
  17. Float getFrequency();
  18. }
  1. package computer;
  2. /**
  3. * 硬盘接口
  4. * @author Jack
  5. *
  6. */
  7. public interface HardDisk {
  8. /**
  9. * 获取硬盘容量
  10. * @return
  11. */
  12. int getCapacity();
  13. }
  1. package computer;
  2. /**
  3. * 内存接口
  4. * @author Jack
  5. *
  6. */
  7. public interface EMS {
  8. /**
  9. * 获取内存容量
  10. * @return
  11. */
  12. int getSize();
  13. }

将接口设计到计算机类中

  1. package computer;
  2. /**
  3. * 计算机类
  4. * @author Jack
  5. *
  6. */
  7. public class Computer {
  8. private CPU cpu;//cpu接口
  9. private HardDisk hardDisk;//硬盘接口
  10. private EMS ems;//内存接口
  11. public Computer() {
  12. }
  13. public Computer(CPU cpu, HardDisk hardDisk, EMS ems) {
  14. super();
  15. this.cpu = cpu;
  16. this.hardDisk = hardDisk;
  17. this.ems = ems;
  18. }
  19. public CPU getCpu() {
  20. return cpu;
  21. }
  22. public void setCpu(CPU cpu) {
  23. this.cpu = cpu;
  24. }
  25. public HardDisk getHardDisk() {
  26. return hardDisk;
  27. }
  28. public void setHardDisk(HardDisk hardDisk) {
  29. this.hardDisk = hardDisk;
  30. }
  31. public EMS getEms() {
  32. return ems;
  33. }
  34. public void setEms(EMS ems) {
  35. this.ems = ems;
  36. }
  37. }

创建 CPU、硬盘、内存接口的实现

  1. package computer.impl;
  2. import computer.CPU;
  3. /**
  4. * 英特尔 CPU
  5. * @author Jack
  6. *
  7. */
  8. public class IntelCPU implements CPU{
  9. @Override
  10. public String getBrand() {
  11. return "英特尔";
  12. }
  13. @Override
  14. public Float getFrequency() {
  15. return 2.3f;
  16. }
  17. }
  1. package computer.impl;
  2. import computer.HardDisk;
  3. /**
  4. * 闪迪硬盘
  5. * @author Jack
  6. *
  7. */
  8. public class SanDisk implements HardDisk{
  9. @Override
  10. public int getCapacity() {
  11. return 3000;
  12. }
  13. }
  1. package computer.impl;
  2. import computer.EMS;
  3. /**
  4. * 金士顿 内存
  5. * @author Jack
  6. *
  7. */
  8. public class JSDEMS implements EMS{
  9. @Override
  10. public int getSize() {
  11. return 4;
  12. }
  13. }

完成计算机及组件的组装进行测试

  1. package computer;
  2. import computer.impl.IntelCPU;
  3. import computer.impl.JSDEMS;
  4. import computer.impl.SanDisk;
  5. public class TestComputer {
  6. public static void main(String[] args) {
  7. CPU cpu=new IntelCPU();//创建CPU
  8. HardDisk sanDisk=new SanDisk();//创建硬盘
  9. EMS jsdEMS=new JSDEMS();//创建内存
  10. Computer computer=new Computer(cpu,sanDisk,jsdEMS);
  11. System.out.println("CPU型号:"+computer.getCpu().getBrand());
  12. System.out.println("硬盘容量:"+computer.getHardDisk().getCapacity()+" GB");
  13. System.out.println("内存容量:"+computer.getEms().getSize()+" GB");
  14. }
  15. }

接口总结

接口有比抽象类更好的特性:

1.可以被多继承

2.设计和实现完全分离

3.更自然的使用多态

4.更容易搭建程序框架

5.更容易更换实现

搜索关注公众号「享智同行」,第一时间获取技术干货

Java入门系列-18-抽象类和接口的更多相关文章

  1. Java基础系列--06_抽象类与接口概述

    抽象类 (1)如果多个类中存在相同的方法声明,而方法体不一样,我们就可以只提取方法声明. 如果一个方法只有方法声明,没有方法体,那么这个方法必须用抽象修饰. 而一个类中如果有抽象方法,这个类必须定义为 ...

  2. Java入门系列之类继承、抽象类、接口(五)

    前言 C#和Java关于类.抽象类.接口使用方式基本相似,只是对应关键字使用不同罢了,本节呢,我们只是对照C#和Java中关于这三个概念在具体使用时,看看有哪些不一样的地方. 类继承 C#和Java在 ...

  3. Java 集合系列18之 Iterator和Enumeration比较

    概要 这一章,我们对Iterator和Enumeration进行比较学习.内容包括:第1部分 Iterator和Enumeration区别第2部分 Iterator和Enumeration实例 转载请 ...

  4. Java入门教程十(抽象类接口内部类匿名类)

    抽象类(abstract) 一个类只定义了一个为所有子类共享的一般形式,至于细节则交给每一个子类去实现,这种类没有任何具体的实例,只具有一些抽象的概念,那么这样的类称为抽象类. 在面向对象领域,抽象类 ...

  5. Java提高篇之抽象类与接口

    接口和内部类为我们提供了一种将接口与实现分离的更加结构化的方法. 抽象类与接口是java语言中对抽象概念进行定义的两种机制,正是由于他们的存在才赋予java强大的面向对象的能力.他们两者之间对抽象概念 ...

  6. Java基础知识(抽象类和接口)

    一.抽象类 在了解抽象类之前,先来了解一下抽象方法.抽象方法是一种特殊的方法:它只有声明,而没有具体的实现.抽象方法的声明格式为: 1 abstract void fun(); 抽象方法必须用abst ...

  7. Java 8 中的抽象类和接口到底有啥区别?

    上一篇栈长发了这篇<Java 8 有多牛逼?打破一切你对接口的认知!>,帮助许多人解开了疑惑,还有读者留言说两者还有啥区别,故引发了此篇: 在我们面试时也会经常遇到面试官问抽象类和接口的区 ...

  8. java提高篇(五)-----抽象类与接口

    接口和内部类为我们提供了一种将接口与实现分离的更加结构化的方法. 抽象类与接口是java语言中对抽象概念进行定义的两种机制,正是由于他们的存在才赋予java强大的面向对象的能力.他们两者之间对抽象概念 ...

  9. 十、Java基础---------面向对象之抽象类与接口

    抽象类(abstract)     当编写一个类时,时常会为该类定义一些方法,这些方法的使用用以描述该类的行为方式,那么这些方法都有具体的方法体.但是在某些情况下,某个父类只是知道子类应该包含怎样的方 ...

随机推荐

  1. duilib入门简明教程 -- 界面设计器 DuiDesigner (10)

       上一个教程讲解了怎么布局最大化.最小化.关闭按钮,但是如果手动去计算这三个按钮的位置和大小的话,非常的不直观,也很不方便.     所以这一章准备介绍duilib的UI设计器,由于这个设计器很不 ...

  2. python学习之路 六 :装饰器

    本节重点: 掌握装饰器相关知识 ​ python装饰器就是用于拓展原来函数功能的一种函数,这个函数的特殊之处在于它的返回值也是一个函数,使用python装饰器的好处就是在不用更改原函数的代码前提下给函 ...

  3. WPF WebBrowser+TabControl MVVM模式 简单应用 提供源码下载

    源代码下载 这个程序是TabControl和Webbrowser的练手小程序 可达到练手目的有: MVVM设计模式的基本使用 Binding(包括相对源[RelativeSource]绑定)的基本使用 ...

  4. Mysql表操作《一》表的增删改查

    一.表介绍 表相当于文件,表中的一条记录就相当于文件的一行内容,不同的是,表中的一条记录有对应的标题,称为表的字段 id,name,qq,age称为字段,其余的,一行内容称为一条记录 二.创建表 语法 ...

  5. 部署LNMP架构及其应用

    部署企业LNMP架构 (一)首先安装nginx服务,具体请见另一篇关于nginx的博文. (二)安装MySQL数据库 .安装前准备 [root@localhost ~]# rpm -e mysql-s ...

  6. (USB HID) Configuration Descriptor

    最近完成了HID的基本收發,使用的配置用了2個Endpoint,把一些特別重要要的地方紀錄下來 整個Configuration 分成4大部分 : 1. Configuration 2. Interfa ...

  7. FPGA基础学习(6) -- 原语

    目录 1. IBUF和IBUFDS(IO) 2. IDDR(Input/Output Functions) 3. IBUFG和IBUFGDS(IO) 原语,即primitive.不同的厂商,原语不同: ...

  8. MySQL压缩版Windows环境进行安装配置

    MySQL下载地址:https://dev.mysql.com/downloads/mysql/ 选择对应的系统和相应的版本后点击Download进入下载页面,不需要登录,点击下面的“No thank ...

  9. centos7安装串口终端kermit

    1. 将usb转串口连接到PC上.通过dmesg命令可以查看USB转串口是否被PC识别.显示 ……attachec to ttyUSB0即被识别. 2. 安装kermit.     [seif@cen ...

  10. 论文阅读 | CornerNet:Detecting Objects as Paired Keypoints

    论文地址:https://arxiv.org/abs/1808.01244v1 论文代码:https://github.com/umich-vl/CornerNet 概述 CornerNet是一篇发表 ...