【发布时间】:2021-11-17 07:13:44
【问题描述】:
谁能告诉我下面的例子是否违反了 LSP?
我有一个例子:
public class Person {
private String name;
private Integer age;
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
public void validate() {
if (age == null || age < 0) {
throw new IllegalArgumentException("Age can not be null");
}
}
}
和子类:
public class Employee extends Person {
private String employeeCode;
public Employee(String name, Integer age, String employeeCode) {
super(name, age);
this.employeeCode = employeeCode;
}
@Override
public void validate() {
super.validate();
if (employeeCode == null) {
throw new IllegalArgumentException("Employee code can not be null");
}
}
}
和主类:
public class Main {
public static void main(String[] args) {
Person person = new Person("Person", 10);
validate(person); // will be ok. does not throw any exception
Person employee = new Employee("Employee", 30, null);
validate(employee); // will be throw IllegalArgumentException because subtype's employee code is null
}
public static void validate(Person p) {
p.validate();
}
}
在此示例中,子类添加名为 employeeCode 的新属性并覆盖方法 validate
额外检查它自己的财产employeeCode。
在 main 方法中,我创建了 2 个对象。第一个是Person 类型的对象,第二个是Employee 类型的对象。
验证人时没问题,因为所有前提条件都可以
但是对于员工来说,它会抛出一个IllegalArgumentException,因为它不符合前置条件
-
Employee是否因在employeeCode上添加新验证而违反 LSP? - 如果 1 是 yes,我该如何重构它以避免违反 LSP?
- 如果 1 是 no,如果我将异常从
IllegalArgumentException("Employee code can not be null")更改为另一个异常NullPointerException。那么它是否因为在子类型中引入了新的异常类型(哪个超类型没有)而违反了 LSP?
【问题讨论】:
-
为了回答这个问题,我们需要知道
validate()方法的完整契约。在像 Java 这样的语言中,方法签名只是contract 的一部分。该方法的前置条件、后置条件和不变量是什么? -
@jaco0646 此方法的不变量是:年龄不能为空或
标签: java solid-principles contract liskov-substitution-principle