1)LSP是否也适用于接口,这意味着我们应该能够使用实现特定接口的类并仍能获得预期的行为?
2)如果确实如此,那么为什么编程接口被认为是好事(顺便说一句 - 我知道对接口的编程会增加松散耦合),如果反对使用继承的主要原因之一是由于不存在风险遵守LSP?也许是因为:
a)松散耦合的好处超重了不遵守LSP的风险
b)与继承相比,类(实现接口)不会附加到LSP的可能性要小得多
谢谢
我对SOLID设计原则很陌生.我理解的一个问题是Liskov Substition Principle违规的"方形矩形"示例.为什么Square的高度/宽度设置器会覆盖矩形的高度?当存在多态性时,这不正是导致问题的原因吗?
不删除这个解决问题?
class Rectangle
{
public /*virtual*/ double Height { get; set; }
public /*virtual*/ double Width { get; set; }
public double Area() { return Height * Width; }
}
class Square : Rectangle
{
double _width;
double _height;
public /*override*/ double Height
{
get
{
return _height;
}
set
{
_height = _width = value;
}
}
public /*override*/ double Width
{
get
{
return _width;
}
set
{
_width = _height = value;
}
} …Run Code Online (Sandbox Code Playgroud) 如果我将子方法添加到子类并且客户端程序调用添加的方法,则客户端程序不能使用父对象而不是子类.
import unittest
class BaseClass(object):
def doSomething(self):
pass
class SubClass(BaseClass):
def doStuff(self):
pass
class Client(object):
def __init__(self, obj):
self.obj = obj
def do(self):
self.obj.doStuff()
class LSPTestCase(unittest.TestCase):
def test_call_subclass_method(self):
client = Client(SubClass())
client.do()
def test_call_baseclass_method(self):
client = Client(BaseClass())
with self.assertRaises(AttributeError):
client.do()
if __name__ == '__main__':
unittest.main()
Run Code Online (Sandbox Code Playgroud)
这种情况违反了LSP?
Arrays.asList(..)返回数组的列表包装器。此包装具有固定的大小,并直接由数组支持,因此,对add()或试图修改列表的其他函数的调用将引发UnsupportedOperationException。
从堆栈溢出中的问题可以明显看出,开发人员常常对此感到惊讶。
但是,根据Liskov替换原理(LSP),List接口具有add()方法,该方法对于List的所有派生类都应该正常工作
Arrays.asList()返回的类型是否是违反Liskov替代原理的示例?
只是对 Stack Overflow 和 Microsoft 开发社区的一个想法和一个关于称为 SOLID 的 OO 软件设计原则的问题。请问Liskov替换原则和依赖倒置原则有什么区别?我已经考虑了一段时间,但我不确定其中的区别。请问你能告诉我吗?非常欢迎任何想法/反馈。
liskov-substitution-principle solid-principles dependency-inversion
ICollection<T>.Add()数组的实现是否违反Liskov替换原则?该方法导致a NotSupportedException,它确实打破了LSP,恕我直言.
string[] data = new string[] {"a"};
ICollection<string> dataCollection = data;
dataCollection.Add("b");
Run Code Online (Sandbox Code Playgroud)
这导致了
未处理的异常:System.NotSupportedException:Collection具有固定大小.
我找到了一个关于 - Stream实现的非常相似的问题.我打开一个单独的问题,因为这个案例非常不同:Liskov替换原则和Streams.这里的不同之处在于,ICollection它不像-class那样提供CanAdd-Property或类似的东西Stream.
考虑这个ruby示例
class Animal
def walk
# In our universe all animals walk, even whales
puts "walking"
end
def run
# Implementing to conform to LSP, even though only some animals run
raise NotImplementedError
end
end
class Cat < Animal
def run
# Dogs run differently, and Whales, can't run at all
puts "running like a cat"
end
def sneer_majesticly
# Only cats can do this.
puts "meh"
end
end
Run Code Online (Sandbox Code Playgroud)
方法是否sneer_majesticly违反LSP,仅在Cat上定义,因为Animal上没有实现这个接口也不需要它?
我一直在寻找代码中的迹象,表明可能会违反里氏替换原则。首先我创建了一个简单的类和另一个继承它的类:
public class Adder
{
public virtual int Add(int operand1, int operand2)
{
return operand1 + operand2;
}
}
public class AdvancedAdder : Adder
{
}
Run Code Online (Sandbox Code Playgroud)
然后我创建了一个检测 LSP 违规的 UnitTest:
public abstract class AdderUnitTestsBase
{
protected static Adder Adder;
[DataTestMethod]
[DataRow(2, 2, 4)]
[DataRow(-1, 2, 1)]
[DataRow(2, -3, -1)]
[DataRow(0, 0, 0)]
public void Add_ReturnsCorrectResult(
int operand1, int operand2, int result)
{
Assert.AreEqual(result, Adder.Add(operand1, operand2));
}
}
[TestClass]
public class AdderUnitTests : AdderUnitTestsBase
{
[ClassInitialize]
public static void ClassInit(TestContext context) …Run Code Online (Sandbox Code Playgroud) 我有以下代码
public class A
{
public double foo(double y)
{
return real_value;
}
}
Run Code Online (Sandbox Code Playgroud)
其中foo方法的输入-1 < y < 1和函数的结果是大于零的实数。
然后我有class B继承class A并覆盖方法的继承foo。
public class B extends A
{
public override double foo(double y)
{
return real_value;
}
}
Run Code Online (Sandbox Code Playgroud)
其中foo方法的输入0 < y < 1和函数的结果是任何实数。
这里是否违反了 Liskov 替换原则?
提前致谢。
liskov-substitution-principle software-design solid-principles
我有一个DataWriter定义抽象方法的抽象类write()。该类应该是一组动态具体类的基类,其中每个类都旨在实现其自己的方法版本write()。为了定义meta方法参数的数据类型,我创建了WriterMetawrite()类型,如下所示:
WriterMeta = typing.Union[GSheetWritable, S3Writable, LocalWritable]
每个具体类将负责处理符合联合的不同类型之一,但 linter mypy似乎没有掌握这一点,因为当我write()使用其中一种类型定义具体类的方法的签名时参数的联合meta,它标记了 a Liskov substituion principle violation,我认为它不存在,因为具体类是抽象类的子集,这意味着父类可以毫无问题地替换子类。
这是我的代码:
class LocalWritable(typing.TypedDict):
file_name: str
class GSheetWritable(typing.TypedDict):
tab_name: str
class S3Writable(typing.TypedDict):
data_name: str
table_name: str
WriterMeta = typing.Union[GSheetWritable, S3Writable, LocalWritable]
class GSheetOutputWriter(DataWriter):
def __init__(
self, google_driver: GoogleApiDriver, folder: str, settings, timestamp, env
):
self._connector = google_driver
self.folder = folder
self.settings = settings
self.timestamp = timestamp
self.env = env
self.file_name …Run Code Online (Sandbox Code Playgroud) python abstract-class liskov-substitution-principle python-3.x mypy