0. 前言
首先声明,本文使用Java所实现OOP对象模型仅包含类、对象、访问控制(private、protected、public三种级别)、多继承(通过优先级来解决冲突)、方法调用等功能,不包含语法,仅用于说明,不可用于工程。
1. 实现效果
LClass aClass = define("A")
.addField("name")
.addField(PUBLIC, "age")
.addField(PROTECTED, "color")
.addField(PRIVATE, "id")
.addMethod("showId", thisPointer -> args -> {
System.out.println(thisPointer.get("id"));
return null;
})
.addMethod(PUBLIC, "setId", thisPointer -> args -> {
thisPointer.set("id", args[0]);
return null;
})
.addMethod(PROTECTED, "changeNameAndPrint", thisPointer -> args -> {
thisPointer.set("name", args[0]);
System.out.println("name change to " + thisPointer.get("name"));
return null;
})
.addMethod(PRIVATE, "changeColor", thisPointer -> args -> {
thisPointer.set("color", args[0]);
return null;
}).end();
LObject aObject = aClass.newInstance();
System.out.println("a object:" + aObject);
aObject.set("name", "ZhouShenshen");
aObject.set("color", "ZhouShenshen");
aObject.set("id", "ZhouShenshen");
aObject.invoke("changeNameAndPrint", "XiaoMing");
aObject.invoke("setId", "1234");
aObject.invoke("showId");
System.out.println("a object:" + aObject);
LClass bClass = define("B", aClass)
.addMethod("setName", thisPointer -> args -> {
thisPointer.set("name", args[0]);
return null;
})
.addMethod("setNameAndPrint", thisPointer -> args -> {
thisPointer.invoke("changeNameAndPrint", args[0]);
return null;
})
.end();
LObject bObject = newInstance(bClass);
bObject.invoke("changeNameAndPrint", "XiaoHua");
bObject.invoke("setNameAndPrint", "XiaoHua");
bObject.invoke("setName", "DingDing");
System.out.println("b object:" + bObject);
2. 代码
2.1 类的实现
类中包含了该类的名称、超类列表、成员集和方法集,定义的过程使用建造者模式实现,代码如下:
public class LClass {
private final String name;
private final List<LClass> superClasses;
private final Map<String, LField> fieldMap;
private final Map<String, LMethod> methodMap;
public LClass(String name, List<LClass> superClasses, Map<String, LField> fieldMap, Map<String, LMethod> methodMap) {
this.name = name;
this.superClasses = superClasses;
this.fieldMap = fieldMap;
this.methodMap = methodMap;
}
List<LClass> getSuperClasses() {
return superClasses;
}
public Map<String, LField> getFieldMap() {
return fieldMap;
}
public String getName() {
return name;
}
public Map<String, LMethod> getMethodMap() {
return methodMap;
}
public LObject newInstance() {
return new LObject(this);
}
public static LObject newInstance(LClass lClass) {
return lClass.newInstance();
}
public static Builder define(String name, LClass... superClasses) {
return new Builder(name, superClasses == null ? Collections.emptyList() : Arrays.asList(superClasses));
}
public static final class Builder {
private final String name;
private final List<LClass> superClasses;
private final Map<String, LField> fieldMap = new HashMap<>();
private final Map<String, LMethod> methodMap = new HashMap<>();
Builder(String name, List<LClass> superClasses) {
this.name = name;
this.superClasses = superClasses;
}
public Builder addField(String name) {
return addField(LModifier.PUBLIC, name);
}
public Builder addField(LModifier modifier, String name) {
fieldMap.put(name, new LField(name, modifier));
return this;
}
public Builder addMethod(String name, Function<LThisPointer, LMethod.MethodImplementor> method) {
return addMethod(LModifier.PUBLIC, name, method);
}
public Builder addMethod(LModifier modifier, String name, Function<LThisPointer, LMethod.MethodImplementor> method) {
methodMap.put(name, new LMethod(modifier, name, method));
return this;
}
public LClass end() {
return new LClass(name, superClasses, fieldMap, methodMap);
}
}
}
2.2 对象的实现
对象中包含该对象所属的类、直接超类的对象列表、成员域集合和This指针,提供方法调用和成员域读写的接口,并做访问控制
public class LObject {
private final LClass objClass;
private final List<LObject> parentObjects;
private final Map<String, LField> fieldMap;
private final LThisPointer thisPointer;
public LObject(LClass objClass) {
this.objClass = objClass;
parentObjects = new ArrayList<>(objClass.getSuperClasses().size());
for (LClass directSuperClass : objClass.getSuperClasses()) {
parentObjects.add(directSuperClass.newInstance());
}
fieldMap = new HashMap<>();
try {
for (Map.Entry<String, LField> entry : objClass.getFieldMap().entrySet()) {
fieldMap.put(entry.getKey(), entry.getValue().clone());
}
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
thisPointer = new LThisPointer(this);
}
public LClass getObjClass() {
return objClass;
}
List<LObject> getParentObjects() {
return parentObjects;
}
Map<String, LField> getFieldMap() {
return fieldMap;
}
public Object invoke(String name, Object... args) {
Queue<LObject> objectQueue = new LinkedList<>();
objectQueue.add(this);
LMethod method = null;
while (!objectQueue.isEmpty()) {
LObject object = objectQueue.remove();
method = object.objClass.getMethodMap().get(name);
if (method != null) {
break;
} else {
objectQueue.addAll(object.parentObjects);
}
}
if (method == null) {
throw new RuntimeException(new NoSuchMethodException(name));//note
} else {
if (method.getModifier() != LModifier.PUBLIC) {
throw new RuntimeException(new IllegalAccessException(method.getModifier().toString()));
} else {
return method.invoke(thisPointer, args);
}
}
}
public Object get(String fieldName) {
try {
return findField(fieldName).getValue();
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
public void set(String fieldName, Object value) {
try {
findField(fieldName).setValue(value);
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
private LField findField(String name) throws NoSuchFieldException, IllegalAccessException {
Queue<LObject> objectQueue = new LinkedList<>();
objectQueue.add(this);
LField field = null;
while (!objectQueue.isEmpty()) {
LObject object = objectQueue.remove();
field = object.fieldMap.get(name);
if (field != null) {
break;
} else {
objectQueue.addAll(object.parentObjects);
}
}
if (field == null) {
throw new NoSuchFieldException(name);
} else {
if (field.getModifier() != LModifier.PUBLIC) {
throw new IllegalAccessException(field.getModifier().toString());
} else {
return field;
}
}
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder().append(objClass.getName()).append('[');
for (LObject object : parentObjects) {
builder.append(object.objClass.getName()).append("=>").append(object).append(',');
}
for (Map.Entry<String, LField> fieldEntry : this.fieldMap.entrySet()) {
builder.append(fieldEntry.getKey()).append("->").append(fieldEntry.getValue().getValue()).append(',');
}
return builder.append(']').toString();
}
}
2.3 this 指针的实现
This 指针提供的接口与对象类似,持有实际对象,但是对对象成员域和方法的访问控制不同,实现如下:
public class LThisPointer {
private final LObject target;
public LThisPointer(LObject target) {
this.target = target;
}
public Object invoke(String name, Object... args) {
LMethod method = target.getObjClass().getMethodMap().get(name);
if (method != null) {
return method.invoke(this, args);
} else {
Queue<LObject> objectQueue = new LinkedList<>(target.getParentObjects());
while (!objectQueue.isEmpty()) {
LObject object = objectQueue.remove();
method = object.getObjClass().getMethodMap().get(name);
if (method != null) {
break;
} else {
objectQueue.addAll(object.getParentObjects());
}
}
if (method == null) {
throw new RuntimeException(new NoSuchMethodException(name));//note
} else {
if (method.getModifier() == LModifier.PRIVATE) {
throw new RuntimeException(new IllegalAccessException(method.getModifier().toString()));
} else {
return method.invoke(this, args);
}
}
}
}
public Object get(String fieldName) {
try {
return findField(fieldName).getValue();
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
public void set(String fieldName, Object value) {
try {
findField(fieldName).setValue(value);
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
private LField findField(String name) throws NoSuchFieldException, IllegalAccessException {
LField field = target.getFieldMap().get(name);
if (field != null) {
return field;
} else {
Queue<LObject> objectQueue = new LinkedList<>(target.getParentObjects());
while (!objectQueue.isEmpty()) {
LObject object = objectQueue.remove();
field = object.getFieldMap().get(name);
if (field != null) {
break;
} else {
objectQueue.addAll(object.getParentObjects());
}
}
if (field == null) {
throw new NoSuchFieldException(name);
} else {
if (field.getModifier() == LModifier.PRIVATE) {
throw new IllegalAccessException(field.getModifier().toString());
} else {
return field;
}
}
}
}
}
2.4 方法的实现
方法的定义通过柯里化的形式,将this指针与方法的实际参数分开传递给方法体,因此方法中仅包含修饰符、名称、以及方法实现,代码如下:
public class LMethod {
private final LModifier modifier;
private final String name;
private final Function<LThisPointer, MethodImplementor> method;
public LMethod(LModifier modifier, String name, Function<LThisPointer, MethodImplementor> method) {
this.modifier = modifier;
this.name = name;
this.method = method;
}
public interface MethodImplementor {
Object run(Object... args);
}
public LModifier getModifier() {
return modifier;
}
public String getName() {
return name;
}
public Object invoke(LThisPointer pointer, Object... args) {
return method.apply(pointer).run(args);
}
}
2.5 成员域的实现
成员域(Field)的实现更为简单,劲爆汗修饰符、名称和值。因为对象创建时需要克隆内容,所以添加了克隆的接口,代码如下:
public class LField implements Cloneable{
private final String name;
private Object value;
private final LModifier modifier;
public LField(String name, LModifier modifier) {
this.name = name;
this.modifier = modifier;
value = null;
}
public String getName() {
return name;
}
public LModifier getModifier() {
return modifier;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
@Override
protected LField clone() throws CloneNotSupportedException {
return (LField) super.clone();
}
}
2.6 访问修饰符
public enum LModifier {
PUBLIC, PROTECTED, PRIVATE
}