1. 引入简单工厂模式:
简单工厂模式:定义一个工厂类,根据传入的参数的值不同返回不同的实例。
- 特点:被创建的实例具有共同的父类或接口
- 适用场景:需要创建对象比较少的情况
- 客户端不关心对象的创建过程
1.1 实现:
DellMouse.java
public class DellMouse implements Mouse{
@Override
public void sayHi() {
System.out.println("dell鼠标");
}
}
HpMouse.java
public class HpMouse implements Mouse{
@Override
public void sayHi() {
System.out.println("HP鼠标");
}
}
MouseFactory.java
public class DellMouse implements Mouse{
@Override
public void sayHi() {
System.out.println("dell鼠标");
}
}
Mouse.interface
public interface Mouse {
public void sayHi();
}
2. 工厂模式:
定义一个用于创建对象的接口,让子类决定实例化哪个类。
- 对象的实例化延迟到其子类
优点:
- 遵循开闭原则
- 对客户端隐藏对象创建细节
- 遵循单一职责
缺点: - 添加子类时“拖家带口”
- 只支持同一类产品的创建
2.1 实现
MouseFactory.interface
public interface MouseFactory {
public Mouse createMouse();
}
HpMouseFactory.java
public class HpMouseFactory implements MouseFactory{
@Override
public Mouse createMouse() {
return new HpMouse();
}
}
DellMouseFactory.java
public class DellMouseFactory implements MouseFactory{
@Override
public Mouse createMouse() {
return new DellMouse();
}
}
FactoryMethodDemo实现
public class FactoryMethodDemo {
public static void main(String[] args) {
MouseFactory mf = new HpMouseFactory();
Mouse mouse = mf.createMouse();
mouse.sayHi();
}
}
3. 抽象工厂模式:
提供一个创建一系列相关或相互依赖对象的接口
- 抽象工厂模式侧重的是同一产品族
- 工厂方法模式更加侧重于同一产品等级
优点:
- 解决了工厂模式只支持生产一种产品的弊端。
- 新增一个产品族,只需要增加一个新的具体工厂,不需要修改代码
缺点: - 新增一个产品类需要更改工厂。违背开闭
3. 1 实现
Keyboard.interface
public interface Keyboard {
void sayHello();
}
HpKeyboard.java
public class HpKeyboard implements Keyboard{
@Override
public void sayHello() {
System.out.println("Hp键盘");
}
}
DellKeyboard.java
public class DellKeyboard implements Keyboard{
@Override
public void sayHello() {
System.out.println("DellKEyboard");
}
}
ComputerFactory.interface
public interface ComputerFactory {
Mouse createMouse();
Keyboard createKeyboard();
}
DellComputerFactory.java
public class DellComputerFactory implements ComputerFactory{
@Override
public Mouse createMouse() {
return new DellMouse();
}
@Override
public Keyboard createKeyboard() {
return new DellKeyboard();
}
}
HpComputerFactory.java
public class HpComputerFactory implements ComputerFactory{
@Override
public Mouse createMouse() {
return new HpMouse();
}
@Override
public Keyboard createKeyboard() {
return new HpKeyboard();
}
}
AbstractDemo.java
public class AbstractDemo {
public static void main(String[] args) {
ComputerFactory cf = new DellComputerFactory();
Keyboard kb= cf.createKeyboard();
kb.sayHello();
Mouse mouse = cf.createMouse();
mouse.sayHi();
}
}
4. 反射:
允许程序在运行时进行自我检查并且对内部的成员进行操作。
作用:
- 在运行时判断任意一个对象所属的类
- 在运行时获取类的对象
- 在运行时访问java对象的属性,方法,构造方法等。
4.1 涉及到的类:
4.1.1 java.lang.reflect:
- Field:表示类中的成员变量
- Method:表示类中的方法
- Constructor:表示类的构造方法
- Array:该类提供了动态创建数组和访问数组元素的静态方法
4.1.2 反射依赖的Class:
用来表示运行时类型信息的对应类,是一个特殊类,(用来存储包含成员变量,成员方法,还有这个类实现的接口,以及这个类的父类等等信息)
- 每个类都有唯一一个与之相对应的Class对象
- Class类为类类型,而Class对象为类类型对象
Class类的特点
- Class类也是类的一种,class则是关键字
- Class类只有一个私有的构造函数,只有JVM能够创建Class类的实例,(通过下1、2图)
- JVM中只有唯一一个和类相对应的Class对象来描述其类型信息
4.1.3 获取Class对象的3种方式:
-
Object -> getClass()
-
任何数据类型(包括基本数据类型)都有一个“静态”的class属性
-
通过Class类的静态方法:forName(String className)(常用)
public class RefectTarget {
public static void main(String[] args) throws ClassNotFoundException {
// 第一种方式获取
RefectTarget refectTarget = new RefectTarget();
Class refectTargetClass1 = refectTarget.getClass();
System.out.println(refectTargetClass1.getName());
// 第二种方式获取
Class refectTargetClass2 = RefectTarget.class;
System.out.println(refectTargetClass2.getName());
System.out.println(refectTargetClass1==refectTargetClass2);
//第三种方式获取
Class refectTargetClass3 = Class.forName("demo.reflect.RefectTarget");
System.out.println(refectTargetClass3.getName());
System.out.println(refectTargetClass3==refectTargetClass2);
}
}
事实证明,三种方式获取的Class对象都是一样的。所以可得:在运行期间,一个类,有且仅有一个Class对象产生。
Class犹如一个镜子,可获得类成员变量,构造方法,成员方法等,这种一种方式就叫“反射”。
4.2 反射的主要用法:
4.2.1 获取类构造方法并使用
1.批量的方法
- public Constructor[] getConstructors(): 获取所有公有的构造方法
- public Constructor[] getDeclaredConstructors(): 获取所有的构造方法(公有,保护,默认,私有)
2.获取单个的方法并调用
- public Constructor getConstructor(Class…parameterTypes): 获取单个公有的构造方法
- public Constructor getDeclaredConstructor(Class…parameterTypes): 获取单个的构造方法(公有,保护,默认,私有)
3.调用构造方法:
- Constructor --> newInstance(Object… initargs)
4.实现:
public class ConstructorColletor {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
// 获取所有公有构造方法
Class clazz = Class.forName("demo.reflect.RefectTarget");
Constructor[] constructors = clazz.getConstructors();
for (Constructor c:constructors){
System.out.println(c);
}
// 获取所有构造方法
Constructor[] constructors1 = clazz.getDeclaredConstructors();
for (Constructor c:constructors1){
System.out.println(c);
}
// 获取单个公有构造方法
// 无参
Constructor constructors2 = clazz.getConstructor(null);
System.out.println(constructors2);
// 两个参数
Constructor constructors3 = clazz.getConstructor(String.class, int.class);
System.out.println(constructors3);
// 获取单个私有构造方法
// 无参
Constructor constructors4 = clazz.getDeclaredConstructor(int.class);
System.out.println(constructors4);
// 调用构造函数
constructors3.newInstance("lyd", 1);
}
}