抽象类

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

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

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

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

抽象父类

public abstract class People {
private String name; public People(String name) {
super();
this.name = name;
} //人类共有方法 哭
public void cry() {
System.out.println("呜呜");
}
//抽象方法 不做具体实现
public abstract void sayHi(); public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}

子类:Chinese.java

//中国人
public class Chinese extends People{ public Chinese(String name) {
super(name);
} //必须实现
@Override
public void sayHi() {
System.out.println(this.getName()+":你好!");
}
}

子类:Britisher.java

//英国人
public class Britisher extends People{ public Britisher(String name) {
super(name);
} @Override
public void sayHi() {
System.out.println(this.getName()+":Hello!");
}
}

测试类

public class TestPeople {

	public static void main(String[] args) {
//People people=new People("张三");//去掉注释试试
People chinese=new Chinese("张三");
chinese.sayHi();
People britisher=new Britisher("John");
britisher.sayHi();
}
}

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

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

抽象方法必须在抽象类里

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

抽象方法没有方法体

public abstract void sayHi();

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

接口

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

接口的语法

public interface MyInterface {
public abstract void foo();
}

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

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

接口不可以被实例化

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

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

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

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

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

父接口:A.java

public interface A {
void methodA();
}

子接口:B.java

public interface B extends A{
void methodB();
}

接口的实现类:C.java

public class C implements B{

	@Override
public void methodA() {
} @Override
public void methodB() {
}
}

接口表示能力

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

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

飞行接口:Fly.java

//表示飞行能力
public interface Fly {
/**
* 飞行
*/
public abstract void fly();
}

游泳接口:Swim.java

//表示游泳能力
public interface Swim {
public abstract void swim();
}

鸟类:Bird.java

//抽象鸟类 重用代码
public abstract class Bird {
/**
* 下蛋
*/
public void layEggs() {
System.out.println("产出一枚蛋");
}
}

白鹭类:Egret.java

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

鸵鸟类:Ostrich.java

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

测试类

public class TestBird {
public static void main(String[] args) {
Egret egret=new Egret();
egret.swim();
egret.fly();
Ostrich ostrich=new Ostrich();
ostrich.swim();
}
}

接口表示约定

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

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

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

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

package computer;

/**
* CPU 接口
* @author Jack
*
*/
public interface CPU {
/**
* 获取CPU品牌
* @return
*/
String getBrand(); /**
* 获取CPU主频
* @return
*/
Float getFrequency();
}
package computer;

/**
* 硬盘接口
* @author Jack
*
*/
public interface HardDisk { /**
* 获取硬盘容量
* @return
*/
int getCapacity();
}
package computer;

/**
* 内存接口
* @author Jack
*
*/
public interface EMS {
/**
* 获取内存容量
* @return
*/
int getSize();
}

将接口设计到计算机类中

package computer;
/**
* 计算机类
* @author Jack
*
*/
public class Computer {
private CPU cpu;//cpu接口
private HardDisk hardDisk;//硬盘接口
private EMS ems;//内存接口 public Computer() {
} public Computer(CPU cpu, HardDisk hardDisk, EMS ems) {
super();
this.cpu = cpu;
this.hardDisk = hardDisk;
this.ems = ems;
} public CPU getCpu() {
return cpu;
} public void setCpu(CPU cpu) {
this.cpu = cpu;
} public HardDisk getHardDisk() {
return hardDisk;
} public void setHardDisk(HardDisk hardDisk) {
this.hardDisk = hardDisk;
} public EMS getEms() {
return ems;
} public void setEms(EMS ems) {
this.ems = ems;
}
}

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

package computer.impl;

import computer.CPU;

/**
* 英特尔 CPU
* @author Jack
*
*/
public class IntelCPU implements CPU{ @Override
public String getBrand() {
return "英特尔";
} @Override
public Float getFrequency() {
return 2.3f;
}
}
package computer.impl;

import computer.HardDisk;

/**
* 闪迪硬盘
* @author Jack
*
*/
public class SanDisk implements HardDisk{ @Override
public int getCapacity() {
return 3000;
}
}
package computer.impl;

import computer.EMS;

/**
* 金士顿 内存
* @author Jack
*
*/
public class JSDEMS implements EMS{ @Override
public int getSize() {
return 4;
}
}

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

package computer;

import computer.impl.IntelCPU;
import computer.impl.JSDEMS;
import computer.impl.SanDisk; public class TestComputer {
public static void main(String[] args) {
CPU cpu=new IntelCPU();//创建CPU
HardDisk sanDisk=new SanDisk();//创建硬盘
EMS jsdEMS=new JSDEMS();//创建内存
Computer computer=new Computer(cpu,sanDisk,jsdEMS);
System.out.println("CPU型号:"+computer.getCpu().getBrand());
System.out.println("硬盘容量:"+computer.getHardDisk().getCapacity()+" GB");
System.out.println("内存容量:"+computer.getEms().getSize()+" GB");
}
}

接口总结

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

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. Javascript 链式作用域 function fn(){}和var fn=function(){}区别

    其实对于Javascript链式作用域的描述,包括,JS权威指南,都有些太冗长了--但是很准确:JavaScript中的函数运行在他们被定义的作用域里,而不是他们被执行的作用域里. 这句话有点难懂,但 ...

  2. 使用 dlv 调试go 程序

    目录 使用 dlv 调试smartraiden 一 正常启动 smartraiden 二 dlv 调试 三 dlv attach 使用 dlv 调试smartraiden by 白振轩 使用 dlv ...

  3. Javascript:日期排班功能实现

     背景: 近期,公司的产品经常会遇到日期排班类似的功能: 需求的排班日期长短不一:有些是两周,有些是四周:要求选中的时候有一个active的状态区分,另外要提供钩子获取选中日期的形如:[2018-04 ...

  4. 支付机构MRC模

    一.电商RFM模型 RFM模型是一个简单的根据客户的活跃程度和交易金额贡献所做的分类.因为操作简单,所以较为常用. 近度R:R代表客户最近的活跃时间距离数据采集点的时间距离,R越大,表示客户越久未发生 ...

  5. leetcode 19. 删除链表的倒数第N个节点 JAVA

    题目: 给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点. 示例: 给定一个链表: 1->2->3->4->5, 和 n = 2. 当删除了倒数第二个节点后,链 ...

  6. 9、select 语句

    基础语句 select * from tb1; select * from tb1 limit 3; select name,age from tb1; select name,age from tb ...

  7. C# Winform下一个热插拔的MIS/MRP/ERP框架15(窗体基类场景1)

    最基础的窗体基类其实是通过应用场景反推的结构. 以下是场景一: 单表应用,普通的数据,比如单位/颜色/特殊字典等使用者少的,无需过多控制的可以使用一个数据表格来管理. 和Excel表格差不多,批量修改 ...

  8. Windows便签快捷键

    Win+R 是运行的快捷件打 StikyNot 回车 快捷键 功能Ctrl+N 新建一张便笺Ctrl+D 删除当前便笺Ctrl+E 居中对齐Ctrl+R 右对齐Ctrl+J 左对齐Ctrl+I 斜体C ...

  9. vue Vue-cli 笔记

    之前用vue写项目都是用的es5,这几天看到小右弄了个命令行工具打算试水一下es6.结果老是报错,但是可以正常编译,虽然我不是处女座但是看到报错很不舒服.结果发现源代码最后一行要空一行,我心想这什么狗 ...

  10. xcode - iPhone Debugging: How to resolve 'failed to get the task for process'? - Stack Overflow

    The program being debugged is not being run. Everyone sees this once in a while during Xcode develop ...