Python 理解里氏替换原则
Python understanding Liskov Substiution Principle
在这个例子中,我是否违反了 LSP?因为直接用 subclass 的实例替换最后两行会给我一个错误(因为工资没有初始化)?
person_1 = Employee('Brad')
person_1.print_name()
@dataclass
class Person:
name: str
def print_name(self):
print(self.name)
@dataclass
class Employee(Person):
wage: int
person_1 = Person('Brad')
person_1.print_name()
如果是这样,那么在扩展 class 的构造函数时怎么可能不违反 LSP(除了之后放置可选属性)?
这取决于你所说的 LSP 是什么意思。
这是否意味着严格的 LSP,就像 Barbara Liskov 的原始论文中那样,程序的行为应该通过类型替换保持不变? (即便如此,它也是一个理想的 属性,而不是绝对的要求)
或者它是否意味着遵循 Person
接口,在这种情况下它不会违规,因为您不能删除 Person
class 中的函数 Employee
class? (好吧,从技术上讲你可以,但这样做并不是一个好主意)。
LSP 说,如果某个 Person 对象为真(例如,它有一个名字,这个名字是一个字符串,它可以打印它的名字),那么它也必须对 Employee 对象为真。换句话说,每个 Employee 也是一个 Person。
它并没有说明 Employee 对象的创建方式必须与 Person 对象相同。每个员工不仅仅是一个人。不仅有名字,还有工资
第二题:
如果 Employee.print_name() 方法被重新定义为不打印名称,而是例如 return 将其作为字符串,那将违反原则。
请注意,破坏 LSP 不需要更改代码,例如,如果将 Person 的名称格式从例如更改为"first_name last_name" 到 Employee 中的 "last_name, first_name",这将导致程序给出不正确的输出。
在这个例子中,我是否违反了 LSP?因为直接用 subclass 的实例替换最后两行会给我一个错误(因为工资没有初始化)?
person_1 = Employee('Brad')
person_1.print_name()
@dataclass
class Person:
name: str
def print_name(self):
print(self.name)
@dataclass
class Employee(Person):
wage: int
person_1 = Person('Brad')
person_1.print_name()
如果是这样,那么在扩展 class 的构造函数时怎么可能不违反 LSP(除了之后放置可选属性)?
这取决于你所说的 LSP 是什么意思。
这是否意味着严格的 LSP,就像 Barbara Liskov 的原始论文中那样,程序的行为应该通过类型替换保持不变? (即便如此,它也是一个理想的 属性,而不是绝对的要求)
或者它是否意味着遵循 Person
接口,在这种情况下它不会违规,因为您不能删除 Person
class 中的函数 Employee
class? (好吧,从技术上讲你可以,但这样做并不是一个好主意)。
LSP 说,如果某个 Person 对象为真(例如,它有一个名字,这个名字是一个字符串,它可以打印它的名字),那么它也必须对 Employee 对象为真。换句话说,每个 Employee 也是一个 Person。
它并没有说明 Employee 对象的创建方式必须与 Person 对象相同。每个员工不仅仅是一个人。不仅有名字,还有工资
第二题:
如果 Employee.print_name() 方法被重新定义为不打印名称,而是例如 return 将其作为字符串,那将违反原则。
请注意,破坏 LSP 不需要更改代码,例如,如果将 Person 的名称格式从例如更改为"first_name last_name" 到 Employee 中的 "last_name, first_name",这将导致程序给出不正确的输出。