抽象方法和抽象类(abstract)
抽象方法和抽象类使用 abstract 来定义,有抽象方法的类必须被定义为抽象类,抽象类里可以没有抽象方法;
抽象方法:只有方法签名,没有方法体的方法;
抽象类不能被实例化,也就是不能通过new关键字去产生对象,只能被继承,但是可以定义变量,任何继承了抽象类的非抽象类的对象可以给这个变量赋值;
抽象类的子类必须实现抽象类里的所有抽象方法,否则这个子类还是抽象类;
抽象类可以包含成员变量、方法(普通方法和抽象方法)、构造器(并不用于创建对象,而是让子类调用,从而完成属于抽象类的初始化操作)、初始化块、内部类(接口、枚举)。
抽象类的作用
抽象类是从多个具有相同特征的具体类中抽象出来的父类,以这个父类作为子类的模板,可以避免子类设计的随意性。
模板方法模式(Template Method)
1. 模板方法模式是由抽象父类控制顶级逻辑,并把某些操作的实现推迟到子类去实现。
2. 如果编写一个抽象父类,父类将部分逻辑以具体方法以及具体构造函数的形式实现,并把不能实现的部分抽成抽象方法,留给其子类去实现,不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现,这种模式就叫模板方法模式。
具体例子:
SpeedMeter - class
上面定义了一个抽象的SpeedMeter类,用来计算车速。该类定义了两个子类通用的方法——设置转速的方法setTurnRate()和计算车速的方法getSpeed(),getSpeed()方法需要知道车轮的半径,但SpeedMeter并不知道车轮的半径,所以将其抽象成抽象方法,交由子类来实现。
CarSpeedMeter - class
BicycleSpeedMeter - class
上面定义了CarSpeedMeter类和BicycleSpeedMeter类,它们均继承自SpeedMeter类,并实现了其父类中的抽象方法getRadius(),其中CarSpeedMeter类的半径是0.31m,BicycleSpeedMeter类的半径是0.33m。
Test - class
上面定义了一个测试类,分别创建了CarSpeedMeter类和BicycleSpeedMeter类的对象,并分别设置它们的转速,最后打印它们各自的车速。
运行结果:
Result
模板方法模式(Template Method)的应用场景
具有统一的操作步骤或操作过程
具有不同的操作细节
存在多个具有同样操作步骤的应用场景,但某些具体的操作细节却各不相同
接口(interface)
接口里可以包含成员变量、方法、内部类(包括内部接口和枚举),不能有构造器和初始化块;
接口里的成员变量必须初始化(即必须赋初值),且均为静态常量(即此值一旦赋值便不能再更改,系统会自动为成员变量添加static和final修饰符,故可以省略);
接口里的方法只能为抽象方法(没有方法体)、类方法(必须使用static修饰,有方法体,Java 8及以上版本支持)、默认方法(必须使用default修饰,有方法体,Java 8及以上版本支持);
一个接口可以从多个接口得到继承(即接口允许多继承,类只能单继承),但不允许接口从类得到继承(即接口只能继承接口);
接口不能被实例化。
接口的语法格式
[修饰符] interface 接口名 { 定义零到多个常量... 定义零到多个抽象方法... 定义零到多个内部类、接口、枚举... 定义零到多个默认方法、类方法(Java 8+)... }
修饰符可以是public或者省略,省略的话默认为default(即包权限)。
接口的用途
定义变量,也可以用于进行强制类型转换
调用接口中定义的常量
被其它类实现
实现接口
1. 一个类只能继承一个类,但可以实现(implements)一个或多个接口(即单继承,多实现);
2. 一个类实现接口后,必须实现接口里的所有抽象方法,否则这个类就成为一个抽象类。
简单工厂模式(Simple Factory Pattern)
1. 简单工厂模式,又叫静态工厂方法(Static Factory Method)模式;
2. 简单工厂模式是由一个工厂对象根据传入的参数,动态地决定创建出哪一种产品类的实例(这产品类往往继承自同一个父类或实现了同一个接口)。
简单工厂模式包含的角色及职责
工厂(Creator)角色
简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类创建产品类的方法可以被外界直接调用,创建所需的产品对象。
抽象产品(Product)角色
简单工厂模式所创建的所有对象的父类(父类可以是接口或抽象类),它负责描述所有实例所共有的公共接口。
具体产品(Concrete Product)角色
简单工厂模式所创建的具体实例对象。
具体例子:
Printer - interface
上面定义了一个Printer接口,在其内部定义了三个抽象方法。
HPPrinter - class
上面定义了一个HPPrinter类,其实现了Printer接口并重写了Printer接口的全部抽象方法。
CanonPrinter - class
上面定义了一个CanonPrinter 类,其实现了Printer接口并重写了Printer接口的全部抽象方法。
PrinterFactory - class
上面定义了一个PrinterFactory类,其有一个返回值类型为Printer的静态方法,根据用户传入的不同参数创建不同的实例。
Test - class
上面定义了一个测试类,用来测试程序。
运行结果:
Result 1
Result 2
从上面的运行结果可以看到,当用户输入不同的参数时,会得到不同的打印机。
简单工厂模式的优缺点
优点:
工厂类是整个模式的关键所在。它包含必要的判断逻辑,能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。用户在使用时可以直接根据工厂类去创建所需的实例,而无需了解这些对象是如何创建以及如何组织的。这有利于整个软件体系结构的优化。
缺点:
由于工厂类集中了所有实例的创建逻辑,将全部创建逻辑集中到了一个工厂类中,导致没有很高的内聚性;同时,工厂类违反了开闭原则,它所能创建的类只能是事先考虑到的,如果需要添加新的类,那就需要改变工厂类了。
参考资料: