Java从零开始学十八(抽象类和接口)
一、什么是抽象类和接口
抽象类、接口与类是一个层次的概念,是java中极其重要的概念。
抽象类是从多个类中抽象出来的公共模板,提供子类均具有的功能。
接口是从多个类中抽象出来的规范,体现的是规范和实现分离的原则,同时也有效的解决了java单重继承的缺陷
二、抽象类
2.1、抽象类与普通类的区别
- 抽象类的class前面有abstract关键字,而普通类没有
/*
* 抽象类
*/
public abstract class Person1 {} /*
* 普通类
*/
public class Person {}
- 抽象类中可以有抽象方法和普通方法,而普通类中只能有普通方法
- 普通类可以实例化使用new,而抽象类不能实例化
2.2、抽象方法与普通方法区别
- 抽象方法的前面有abstract关键字,而普通方法没有
- 抽象方法没有方法体,而普通方法有方法体
/*
* 抽象方法
*/
public abstract void show();
//没有方法体 /*
* 普通方法
*/
public void show(){
System.out.println("这是个普通方法");
}
/*
* 普通类中不能有抽象方法
*/
2.3、完整对比2个类
package com.pb.demo3;
/*
* 普通类
*/
public class Person {
private String name; //名称
private int age ; //年龄 /*
* 普通方法
*/
public void show(){
System.out.println("这是个普通方法");
}
/*
* 普通类中不能有抽象方法
*/ //setter/getter方法
public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} }
package com.pb.demo3;
/*
* 抽象类
*/
public abstract class Person1 {
private String name; //名称
private int age ; //年龄 /*
* 抽象方法
*/
public abstract void show();
//没有方法体 //抽象类中可以有普通方法
public void printSelf(){
System.out.println("这是个抽象类中的普通方法"); }
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
} }
2.4、如果抽象类被继承
- 如果子类不是抽象类,则必须重写父类抽象类的全部抽象方法。(普通方法选择重写或者不写)
package com.pb.demo3;
/*
* 学生类继承Person1抽象类
*/
public class Student extends Person1 { //继承时,会强制要求重写父类的抽象方法
@Override
public void show() {
System.out.println("重写父类的抽象方法"); } }
2.5 、一些注意事项
- abstract不能与final关键字一起使用
- private 关键字不能修饰抽象方法
- abstract修饰的抽象方法没有方法体
2.6、图像对比

三、接口
3.1、接口定义
接口使用interface关键字来定义
简单的说,接口是一个不能实例化,且只能拥有抽象方法的类型
public interface 接口名称{
抽象方法
}
public interface Person {
}
package com.pb.demo4;
public interface Person {
/*
* 定义2个抽象方法
*/
public void run();
public void say();
}
3.2.为什么接口中的抽象方法不用使用abstract关键字?
因为接口中只能有抽象方法,所以不必专门使用abstract关键字来修饰,当然也可以加上不过完全没有必要
3.3、接口的抽象方法
接口的抽象方法只能由public来修饰
四、使用抽象类和接口
4.1、抽象类使用继承来实现
/*
* 抽象类
*/
public abstract class Person { /*
* 普通方法
*/
public void run(){
System.out.println("抽象类的普通方法! 走一走");
} /*
* 抽象方法
*/
public abstract void say();
}
/*
* 继承抽象类
*/
public class Student extends Person{ @Override
public void say() {
System.out.println("实现父类的抽象方法!说一说"); } }
public class Test {
public static void main(String[] args) {
//声明子类对象
Student stu=new Student();
//调用子类重写的方法
stu.say();
//调用父类的普通方法
stu.run();
}
}
结果:
实现父类的抽象方法!说一说
抽象类的普通方法! 走一走
4.2、接口的使用
使用implements来实现接口,解决java中单继承的关系,接口可以是多个
package com.pb.demo4;
public interface Person {
/*
* 定义2个抽象方法
*/
public void run();
public void say();
}
package com.pb.demo4; /*
* 实现接口Person
*/
public class PersonImp implements Person { /*
* 必须重写接口的全部抽象方法
*/
@Override
public void run() {
System.out.println("实现接口的走一走抽象方法"); } @Override
public void say() {
System.out.println("实现接口的说一说抽象方法"); } }
package com.pb.demo4;
public class Test {
public static void main(String[] args) {
//声明对象
PersonImp p=new PersonImp();
//调用实现的方法
p.run();
p.say();
}
}
结果:
实现接口的走一走抽象方法
实现接口的说一说抽象方法
4.3 、对比实现

五、抽象类和接口的简单区别
5.1、区别
- 抽象类使用abstract声明,接口使用interface声明
- 抽象类可以有抽象方法也可以有普通方法,接口只能有抽象方法
- 实现方式不同:抽象类使用继承extends来实现,接口使用implements来实现
5.2、相同点
- 抽象类和接口都不能实例化
5.3、图形对比

5.4、使用规则
- 抽象类和接口都不能实例化
- 抽象类与接口分别被继承与实现的场合,其子类必须实现其中的抽象方法
- 抽象类中的抽象方法访问修饰符不能为private,接口中的抽象方法访问修饰符必须为public

六、简单实现抽象类
package com.pb.demo5;
/*
* 鸟类抽象类
*/
public abstract class Bird { /*
* 飞的普通方法
*/
public void fly(){
System.out.println("弹射飞!");
}
/*
* 攻击抽象方法
*/
public abstract void attack(); }
package com.pb.demo5;
/*
* 火箭鸟
*/
public class RocketBird extends Bird { /*
* 重写攻击方法
*/
@Override
public void attack() {
System.out.println("火箭鸟攻击方式:加速冲撞!"); } }
package com.pb.demo5;
/*
* 分裂鸟
*/
public class SplittBird extends Bird { /*
* 重写攻击方法
*/
@Override
public void attack() {
System.out.println("分裂鸟攻击方式:分裂攻击!");
} }
package com.pb.demo5;
public class Test {
public static void main(String[] args) {
/*
* 多态的应用
*/
//创建鸟类对象,实例化为分裂鸟对象
Bird splitbird=new SplittBird();
//创建鸟类对象,实例化为火箭鸟对象
Bird rocketbird=new RocketBird();
//分别调用鸟类的普通飞的方法
//分别调用子类重写后的叫方法
//分别调用子类重写后的攻击方法
splitbird.fly();
splitbird.attack();
rocketbird.fly();
rocketbird.attack();
}
}
结果:
弹射飞!
分裂鸟攻击方式:分裂攻击!
弹射飞!
火箭鸟攻击方式:加速冲撞!
从上例子中可以看出:子类相同的方法,如:飞的方法 可以放在父类的抽象类中使用普通方法实现,实现代码的重用,而不同的部分,使用抽象方法,子类来实现自己的方法,简单来讲:抽象类就是抽取公共的部分在抽象来中来实现
如:完全没有相同的方法,但都有这此方法,该怎么实现呢?这时候就需要接口大神出场
七、简单接口实现
还是以上例为例,比如,连有叫的方法,但每种 鸟的叫声都不一样呢?有的会叫,有的不会叫,
package com.pb.demo5;
/*
* 叫的接口
*/
public interface Shout {
/*
* 叫的方法
*/
public void shout();
}
package com.pb.demo5; public class AoShoutImpl implements Shout { @Override
public void shout() {
System.out.println("嗷嗷叫!"); } }
package com.pb.demo5; public class ZhaShoutImpl implements Shout { @Override
public void shout() {
System.out.println("喳喳叫!"); } }
package com.pb.demo5; public class NoCanShoutImpl implements Shout { @Override
public void shout() {
System.out.println("不会叫!"); } }
package com.pb.demo5;
/*
* 鸟类抽象类
*/
public abstract class Bird {
Shout shout; /*
* 构造方法
*/ public Bird(Shout shout) {
super();
this.shout = shout;
}
/*
* 叫的普通方法
*/
public void shout(){
//调用自身叫的方法
shout.shout();
} /*
* 飞的普通方法
*/
public void fly(){
System.out.println("弹射飞!");
} /*
* 抽象攻击方法
*/
public abstract void attack(); }
package com.pb.demo5; /*
* 炸弹鸟
*/
public class Bombbird extends Bird { public Bombbird(Shout shout) {
super(shout);
} @Override
public void attack() {
System.out.println("炸弹鸟攻击方式:炸弹攻击"); } @Override
public void shout() {
System.out.println("炸弹鸟:喳喳叫!"); } }
package com.pb.demo5; /*
* 胖子鸟
*/
public class Fatbird extends Bird { public Fatbird(Shout shout) {
super(shout); } @Override
public void attack() {
System.out.println("胖子鸟攻击方式:下蛋攻击"); } @Override
public void shout() {
System.out.println("胖子鸟:不会叫!"); } }
package com.pb.demo5; /*
* 红色鸟
*/
public class Redbird extends Bird { public Redbird(Shout shout) {
super(shout); } @Override
public void attack() {
System.out.println("红色鸟攻击方式:普通攻击"); } @Override
public void shout() {
System.out.println("红色鸟:喳喳叫!"); } }
package com.pb.demo5; import com.pb.demo5.Bird; /*
* 火箭鸟
*/
public class RocketBird extends Bird { public RocketBird(Shout shout) {
super(shout); } /*
* 重写攻击方法
*/
@Override
public void attack() {
System.out.println("火箭鸟攻击方式:加速冲撞!"); } /*
* 重写叫的方法
*/
@Override
public void shout() {
System.out.println("火箭鸟:嗷嗷叫!"); } }
package com.pb.demo5; /*
* 分裂鸟
*/
public class SplittBird extends Bird { public SplittBird(Shout shout) {
super(shout); }
/*
* 重写攻击方法
*/
@Override
public void attack() {
System.out.println("分裂鸟攻击方式:分裂攻击!");
}
/*
* 重写叫的方法
*/
@Override
public void shout() {
System.out.println("分裂鸟:嗷嗷叫!"); } }
package com.pb.demo5;
import com.pb.demo5.Bird;
public class Test {
public static void main(String[] args) {
/*
* 创建接口对象
*/
Shout aoshout=new AoShoutImpl();
Shout zhashout=new ZhaShoutImpl();
Shout noshout=new NoCanShoutImpl();
/*
* 多态的应用
*/
//创建鸟类对象,实例化为分裂鸟对象
Bird splitbird=new SplittBird(aoshout);
Bird rocketbird=new RocketBird(aoshout);
Bird bomb=new Bombbird(zhashout);
Bird redbird=new Redbird(zhashout);
Bird fatbird=new Fatbird(noshout);
splitbird.fly();
splitbird.attack();
splitbird.shout();
rocketbird.fly();
rocketbird.shout();
rocketbird.attack();
bomb.fly();
bomb.shout();
bomb.attack();
redbird.fly();
redbird.shout();
redbird.attack();
fatbird.fly();
fatbird.shout();
fatbird.attack();
}
}
结果:
弹射飞!
分裂鸟攻击方式:分裂攻击!
分裂鸟:嗷嗷叫!
弹射飞!
火箭鸟:嗷嗷叫!
火箭鸟攻击方式:加速冲撞!
弹射飞!
炸弹鸟:喳喳叫!
炸弹鸟攻击方式:炸弹攻击
弹射飞!
红色鸟:喳喳叫!
红色鸟攻击方式:普通攻击
弹射飞!
胖子鸟:不会叫!
胖子鸟攻击方式:下蛋攻击
由上可以看出:抽象类方便代码复用,接口方便代码维护
Java从零开始学十八(抽象类和接口)的更多相关文章
- 夯实Java基础(十)——抽象类和接口
转载自:http://cmsblogs.com/ 该博主的网站上干货非常!非常!非常多(说三遍),强烈推荐大家前去学习. 接口和内部类为我们提供了一种将接口与实现分离的更加结构化的方法 抽象类与接口是 ...
- Java从零开始学十九(异常)
一.什么是异常 从字面上讲,就是不正常的现实就是异常. 程序中的异常也是要在程序运行中才会偶尔发生.如果程序还没有运行,编译就报错,这种不叫异常,这种叫编译错误,通常是语法上的错误 二.java中异常 ...
- Java从零开始学二十三(集合Map接口)
一.Map接口 Collection.Set.List接口都属于单值的操作,即:每次只能操作一个对象,而Map与它们不同的是,每次操作的是一对对象,即二元偶对象,Map中的每个元素都使用key à v ...
- Java从零开始学二十一(集合List接口)
一.List接口 List是Collection的子接口,里面可以保存各个重复的内容,此接口的定义如下: public interface List<E> extends Collecti ...
- Java从零开始学十四(包和访问控制)
一.java中的包 Java文件的组织形式Windows中的文件功能类似 在开发比较大的项目时,不可能只涉及到一个java文件,可能要创建几十,甚至几百个java文件,这个时候,我们就可以使用包,把相 ...
- Java从零开始学十六(多态)
一.什么是多态 多态性是指允许不同类的对象对同一消息作出响应.多态性包括参数化多态性和包含多态性.多态性语言具有灵活.抽象.行为共享.代码共享的优势,很好的解决了应用程序函数同名问题.多态有两种表现形 ...
- Java从零开始学十五(继承)
一.继承作用 继承使用复用以前的代码非常容易,能够大大的缩短开发周期,降低开发成本,同时增加程序的易维护性 继承使重一个类A能够直接使用另外一个类B的属性和方法的一种途径 类A可以有自己的属性和方法 ...
- Java从零开始学十(Arrays类对数组的常用方法)
一.Arrays类常用方法 二.简单例子 package com.pb.demo1; import java.util.Arrays; /* * Arrays工具类的中的几个常用方法 * 1.copy ...
- Java从零开始学十二(构造方法)
一.构造方法 构造方法的主要目的是为类中的属性初始化 二.构造方法的定义格式 class 类名称{ 访问权限 类名称(类型1 参数1,类型2 参数2,…){ 程序语句 ; … // 构造方法没有 ...
随机推荐
- visio2013 激活工具,仅供交流学习
visio2013激活软件 环境是 win7, 64 bit 装了 visio 2013 , 可以却不能用它来画图,在网上找了一些破解工具,大都不能解决问题.网上不靠谱的广告型文章太多了 所幸,终于找 ...
- LogStash日志分析系统
简介 通常日志管理是逐渐崩溃的——当日志对于人们最重要的时候,也就是出现问题的时候,这个渐进的过程就开始了.日志管理一般会经历一下3个阶段: 初级管理员将通过一些传统工具(如cat.tail.sed. ...
- Linux High Availabi RHCS
-----本文大纲 简介 术语 环境配置 实现过程 命令行管理工具 ------------- 一.简介 RHCS 即 RedHat Cluster Suite ,中文意思即红帽集群套件.红帽集群套件 ...
- mysql的性能监控指标(转载)
这里列出了一些如何监视你安装的mysql性能的一些ideas.监视总是一个持续的过程.你需要知道哪种模式对你的数据库是好的,什么是问题的表象,甚至是危险的情况.一下列出了用来去监视你的系统的主要参数: ...
- 知识共享 - creative commons
Creative Commons,简称CC,中国大陆正式名称为知识共享,台湾正式名称为创用CC. 是一个非营利组织,也是一种创作的授权方式. 此组织的主要宗旨是增加创意作品的流通可及性,作为其他人据以 ...
- jquery easyui combobox设置默认选中第一项
combobox的内容是从后台获取的json, js截取: var data = $('#id').combobox('getData'); $("#id ").combobox( ...
- 完整的POM文档内容
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...
- SQLite 管理工具 SQLite Expert
SQLite Expert – Personal Edition SQLite Expert 提供两个版本,分别是个人版和专业版.其中个人版是免费的,提供了大多数基本的管理功能. SQLite Exp ...
- 报错:未能加载文件或程序集“WebGrease, Version=1.5.1.25624, Culture=neutral, PublicKeyToken=31bf3856ad364e35”或它的某一个依赖项。找到的程序集清单定义与程序集引用不匹配。 (异常来自 HRESULT:0x80131040)
□ 背景 通过NuGet安装某程序包后,运行程序出现如上错误. □ 分析 可能是程序集版本不兼容引起的,可以通过NuGet先把程序包删除,然后再安装最新或某个版本的程序包. □ 解决方法 通过 ...
- DockManager如何停靠 z
DockManager默认只能停靠在窗体上,如果想停靠在其他控件上,我们发现并没有选项可以选,可能目前大部分解决方法是新建一个用户控件文件,再在用户控件里面单独设计模块. 除了这种方法还有没有其他的呢 ...