- 10.6 抽象类
- 10.6.1 先看一个问题、问题解决之道
- 10.6.2 抽象类的介绍
- 10.6.3 抽象类使用的注意事项和细节讨论
- 10.6.4 课堂练习题
- 10.7 抽象类最佳实践-模板设计模式
- 10.7.1 基本介绍、模板设计模式能解决的问题
- 10.7.2 最佳实践
- 10.8 接口
- 10.8.1 为什么有接口、接口快速入门
- 10.8.2 基本介绍
- 10.8.3 深入讨论接口
- 10.8.4 注意事项和细节
Abstract01.java
-
问题
-
解决之道-抽象类快速入门
当父类的一些方法不能确定时,可以用abstract关键字来修饰该方法,这个方法就是抽象方法,用abstract 来修饰该类就是抽象类。
我们看看如何把Animal做成抽象类,并让子类Cat类实现。
abstract class Animal{
String name;
int age;
abstract public void cry();
代码:
public class Abstract01 {
public static void main(String[] args) {
}
}
abstract class Animal {
private String name;
public Animal(String name) {
this.name = name;
}
//思考:这里eat 这里你实现了,其实没有什么意义
//即: 父类方法不确定性的问题
//===> 考虑将该方法设计为抽象(abstract)方法
//===> 所谓抽象方法就是没有实现的方法
//===> 所谓没有实现就是指,没有方法体
//===> 当一个类中存在抽象方法时,需要将该类声明为abstract类
//===> 一般来说,抽象类会被继承,有其子类来实现抽象方法.
// public void eat() {
// System.out.println("这是一个动物,但是不知道吃什么..");
// }
public abstract void eat() ;
}
10.6.2 抽象类的介绍
- 用abstract关键字来修饰一个类时,这个类就叫抽象类,访问修饰符 abstract类名{ }
- 用abstract关键字来修饰一个方法时,这个方法就是抽象方法
访问修饰符 abstract 返回类型 方法名 (参数列表) ; //没有方法体,即不加 { } - 抽象类的价值更多作用是在于设计,是设计者设计好后,让子类继承并实现抽象类()
- 抽象类,是考官比较爱问的知识点,在框架和设计模式使用较多
AbstractDetail01.java
- 抽象类不能被实例化 , [举例]
- 抽象类不一定要包含abstract方法。也就是说,抽象类里边可以没有abstract方法 , [举例]
- 一旦类包含了abstract方法,则这个类必须声明为abstract [说明]
- abstract只能修饰类和方法,不能修饰属性和其它的。[说明]
- 抽象类可以有任意成员【抽象类本质还是类】,比如:抽象类可以有非抽象方法、构造器、静态属性等等
- 抽象方法不能有主体,即不能实现.如图所示
abstract void aaa ( ) { } ;//是错误的,不能有 { } 方法。 - 如果一个类继承了抽象类,则它必须实现抽象类的所有抽象方法,除非它自己也声明为abstract类。
- 抽象方法不能使用private、final和static来修饰,因为这些关键字都是和重写相违背的。
细节1-4对应代码:
public class AbstractDetail01 {
public static void main(String[] args) {
//抽象类,不能被实例化
//new A();
}
}
//抽象类不一定要包含abstract方法。也就是说,抽象类里边可以没有abstract方法
//,还可以有实现的方法。
abstract class A {
public void hi() {
System.out.println("hi");
}
}
//一旦类包含了abstract方法,则这个类必须声明为abstract
abstract class B {
public abstract void hi();
}
//abstract 只能修饰类和方法,不能修饰属性和其它的
class C {
// public abstract int n1 = 1;
}
细节 5 - 8 对应代码:
public class AbstractDetail02 {
public static void main(String[] args) {
System.out.println("hello");
}
}
//抽象方法不能使用private、final 和 static来修饰,因为这些关键字都是和重写相违背的
abstract class H {
public abstract void hi();//抽象方法
}
//如果一个类继承了抽象类,则它必须实现抽象类的所有抽象方法,除非它自己也声明为abstract类
abstract class E {
public abstract void hi();
}
abstract class F extends E {
}
class G extends E {
@Override
public void hi() { //这里相等于G子类实现了父类E的抽象方法,所谓实现方法,就是有方法体
}
}
//抽象类的本质还是类,所以可以有类的各种成员
abstract class D {
public int n1 = 10;
public static String name = "java教育";
public void hi() {
System.out.println("hi");
}
public abstract void hello();
public static void ok() {
System.out.println("ok");
}
}
10.6.4 课堂练习题
第4题代码:
抽象类Employee:
abstract public class Employee {
private String name;
private int id;
private double salary;
public Employee(String name, int id, double salary) {
this.name = name;
this.id = id;
this.salary = salary;
}
//将work做成一个抽象方法
public abstract void work();
//get set方法
public String getName() { return name; }
public void setName(String name) {this.name = name;}
public int getId() {return id;}
public void setId(int id) {this.id = id;}
public double getSalary() {return salary;}
public void setSalary(double salary) {this.salary = salary;}
}
子类Manager:
public class Manager extends Employee {
private double bonus;
public Manager(String name, int id, double salary) {
super(name, id, salary);
}
public double getBonus() { return bonus; }
public void setBonus(double bonus) {this.bonus = bonus;}
@Override // 如果一个类继承了抽象类,则它必须实现抽象类的所有抽象方法,除非它自己也声明为abstract类。
public void work() {
System.out.println("经理 " + getName() + " 工作中..."); //重写
}
}
子类CommonEmployee类:
public class CommonEmployee extends Employee{
public CommonEmployee(String name, int id, double salary) {
super(name, id, salary);
}
@Override
public void work() {
System.out.println("普通员工 " + getName() + " 工作中...");
}
}
主类:
public class AbstractExercise01 {
public static void main(String[] args) {
//测试
Manager jack = new Manager("jack", 999, 50000);
jack.setBonus(8000);
jack.work();
CommonEmployee tom = new CommonEmployee("tom", 888, 20000);
tom.work();
}
}
10.7 抽象类最佳实践-模板设计模式
10.7.1 基本介绍、模板设计模式能解决的问题
- 基本介绍
抽象类体现的就是一种模板模式的设计,抽象类作为多个子类的通用模板,子类在抽象类的基础上进行扩展、改造,但子类总体上会保留抽象类的行为方式。 - 模板设计模式能解决的问题
- 当功能内部一部分实现是确定,一部分实现是不确定的。这时可以把不确定的部分暴露出去,让子类去实现。
- 编写一个抽象父类,父类提供了多个子类的通用方法,并把一个或多个方法留给其子类实现,就是一种模板模式.
需求:
- 有多个类,完成不同的任务job
- 要求统计得到各自完成任务的时间
- 请编程实现 TestTemplate.java
感情的自然流露
- 先用最容易想到的方法-》代码实现
- 分析问题,提出使用模板设计模式
代码:
public class LianXi {
public static void main(String[] args) {
AA aa = new AA();
aa.calculateTime(); //这里还是需要有良好的OOP基础,对多态
BB bb = new BB();
bb.calculateTime();
}
}
abstract class Template { //抽象类-模板设计模式
public abstract void job();//抽象方法
public void calculateTime() {//实现方法,调用job方法
//得到开始的时间
long start = System.currentTimeMillis();
job(); //动态绑定机制
//得的结束的时间
long end = System.currentTimeMillis();
System.out.println("任务执行时间 " + (end - start));
}
}
class AA extends Template {
//计算任务
//1+....+ 800000
@Override
public void job() { //实现Template的抽象方法job
long num = 0;
for (long i = 1; i <= 800000; i++) {
num += i;
}
}
}
class BB extends Template{
public void job() {//这里也去,重写了Template的job方法
long num = 0;
for (long i = 1; i <= 80000; i++) {
num *= i;
}
}
}
10.8 接口
10.8.1 为什么有接口、接口快速入门
-
为什么有接口
-
接口快速入门
这样的设计需求在java编程/php/ .net/go中也是会大量存在的,我曾经说过,一个程序就是一个世界,在现实世界存在的情况,在程序中也会出现。我们用程序来模拟一下。
代码:
public class LianXi {
public static void main(String[] args) {
//创建手机,相机对象
//Camera 实现了 UsbInterface
Camera camera = new Camera();
//Phone 实现了 UsbInterface
Phone phone = new Phone();
//创建计算机
Computer computer = new Computer();
computer.work(phone);//把手机接入到计算机
System.out.println("===============");
computer.work(camera);//把相机接入到计算机
}
}
interface UsbInterface { //接口
//规定接口的相关方法,老师规定的.即规范...
public void start();
public void stop();
}
//Phone 类 实现 UsbInterface
//解读1. 即 Phone类需要实现 UsbInterface接口 规定/声明的方法
class Phone implements UsbInterface {
@Override
public void start() {
System.out.println("手机开始工作...");
}
@Override
public void stop() {
System.out.println("手机停止工作.....");
}
}
class Camera implements UsbInterface{//实现接口,就是把接口方法实现
@Override
public void start() {
System.out.println("相机开始工作...");
}
@Override
public void stop() {
System.out.println("相机停止工作....");
}
}
class Computer {
//编写一个方法, 计算机工作
//解读:
//1. UsbInterface usbInterface 形参是接口类型 UsbInterface
//2. 看到 接收 实现了 UsbInterface接口的类的对象实例
public void work(UsbInterface usbInterface) {
//通过接口,来调用方法
usbInterface.start();
usbInterface.stop();
}
}
10.8.2 基本介绍
代码:
public class LianXi {
public static void main(String[] args) {
}
}
interface AInterface {
//可以写属性
public int n1 = 10;
//可以写方法
//在接口中,抽象方法,可以省略abstract关键字
public void hi();
//在jdk8后,可以有默认实现方法,但是需要使用default关键字修饰
default public void ok() {
System.out.println("ok ...");
}
//在jdk8后, 可以有静态方法
public static void cry() {
System.out.println("cry ....");
}
}
//解读
//1.如果一个类 implements实现 接口
//2. 需要将该接口的所有抽象方法都实现
class A implements AInterface {
@Override
public void hi() {
System.out.println("hi()....");
}
}
10.8.3 深入讨论接口
对初学者讲,理解接口的概念不算太难难的是不知道什么时候使用接口,下面我例举几个应用场景:
- 说现在要制造战斗机,武装直升机.专家只需把飞机需要的功能/规格定下来即可,然后让别的人具体实现就可。
- 说现在有一个项目经理(段玉),管理三个程序员,功能开发一个软件为了控制和管理软件,项目经理可以定义一些接口,然后由程序员具体实现。(1.项目质量2.项目进度3.项目奖)参加工作
假如现在有实际要求:3个程序员;编写三个类,分别完成对Mysql,Oracle,DB2数据库的连接 connect, close…
代码:
public class LianXi {
public static void main(String[] args) {
MysqlDB mysqlDB = new MysqlDB();
t(mysqlDB);
OracleDB oracleDB = new OracleDB();
t(oracleDB);
}
public static void t(DBInterface db) {
db.connect();
db.close();
}
}
interface DBInterface { //项目经理写的
public void connect();//连接方法
public void close();//关闭连接
}
class MysqlDB implements DBInterface { //A程序员写的连接mysql的
@Override
public void connect() {
System.out.println("连接mysql");
}
@Override
public void close() {
System.out.println("关闭mysql");
}
}
class OracleDB implements DBInterface{//B程序员写的连接oracle的
@Override
public void connect() {
System.out.println("连接oracle");
}
@Override
public void close() {
System.out.println("关闭oracle");
}
}
10.8.4 注意事项和细节
- 接口不能被实例化
- 接口中所有的方法是public方法,接口中抽象方法,可以不用abstract修饰,图示:
void aaa () ; 实际上是 abstract void aaa(); - 一个普通类实现接口,就必须将该接口的所有方法都实现。
- 抽象类实现接口,可以不用实现接口的方法。
细节1-4点代码:
public class InterfaceDetail01 {
public static void main(String[] args) {
//new IA(); //接口不能被实例化
}
}
//1.接口不能被实例化
//2.接口中所有的方法是 public方法,接口中抽象方法,可以不用abstract 修饰
//3.一个普通类实现接口,就必须将该接口的所有方法都实现,可以使用alt+enter来解决
//4.抽象类去实现接口时,可以不实现接口的抽象方法
interface IA {
void say();//修饰符 public protected 默认 private
void hi();
}
class Cat implements IA{
@Override
public void say() {
}
@Override
public void hi() {
}
}
abstract class Tiger implements IA { //如果不写abstract就会报错
}



