相关疑难解决方法(0)

任何人都可以使用车辆提供Liskov替代原则(LSP)的示例吗?

Liskov替换原则规定子类型应该可替代该类型(不改变程序的正确性).

  • 有人可以在车辆(汽车)领域提供这个原则的例子吗?
  • 有人可以提供一个在车辆领域违反这一原则的例子吗?

我已经读过关于方形/矩形的例子,但我认为车辆的一个例子可以让我更好地理解这个概念.

oop liskov-substitution-principle solid-principles

33
推荐指数
2
解决办法
1万
查看次数

测试对象是否实现接口有什么问题?

这个答案的评论中,声明" 检查对象是否实现了界面 ,尽管可能是猖獗的,但这是件坏事 "

以下是我认为这种做法的一个例子:

public interface IFoo
{
   void Bar();
}

public void DoSomething(IEnumerable<object> things)
{
   foreach(var o in things)
   {
       if(o is IFoo)
           ((IFoo)o).Bar();
   }
}
Run Code Online (Sandbox Code Playgroud)

由于我的好奇心激起了以前曾使用过这种模式的变化,我搜索了一个很好的例子或解释为什么它是一件坏事并且无法找到它.

虽然我很可能误解了评论,但有人可以提供一个示例或链接来更好地解释评论吗?

c# oop polymorphism

30
推荐指数
4
解决办法
1458
查看次数

继承还是构成:依靠"is-a"和"has-a"?

当我设计类并且必须在继承和组合之间进行选择时,我通常使用经验法则:如果关系是"is-a" - 使用继承,如果关系是"has-a" - 使用组合.

总是对的吗?

谢谢.

c++ oop inheritance

28
推荐指数
3
解决办法
2万
查看次数

为什么PHP允许"不兼容"的构造函数?

这里有几个片段:

  1. 重写构造函数方法有一个额外的参数.

    class Cat {
        function __construct() {}
    }
    
    class Lion extends Cat {
        function __construct($param) {}
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 覆盖(常规)方法有一个额外的参数.

    class Cat {
        function doSomething() {}
    }
    
    class Lion extends Cat {
        function doSomething($param) {}
    }
    
    Run Code Online (Sandbox Code Playgroud)

第一个会起作用,而第二个会起作用Declaration of Lion::doSomething() should be compatible with that of Cat::doSomething().

为什么对构造方法有特殊态度?

php oop constructor

27
推荐指数
3
解决办法
2773
查看次数

接口是否与多态性兼容

我遇到了与多态类型(甚至多态接口)交互的接口概念的问题.我正在开发C#并希望接近这个定义的答案,尽管我认为这仍然为每个人提供了足够的空间来提出答案.

举个例子,假设你想制作一个绘制东西的程序.您可以为Paints定义一个接口,并为绘制的主体定义一个接口.此外,您还可以使用更具体的方式绘制一些主题.

interface IPainter {
  void paint(IPaintable paintable);
}
interface IPaintable {
  void ApplyBaseLayer(Color c);
}
interface IDecalPaintable : IPaintable {
  void ApplyDecal(HatchBrush b);
}
Run Code Online (Sandbox Code Playgroud)

我可以想象制作一个类似于以下的画家:

class AwesomeDecalPainter : IPainter
  {
    public void paint(IPaintable paintable) {
      IDecalPaintable decalPaintable = (IDecalPaintable)paintable;
      decalPaintable.ApplyBaseLayer(Color.Red);
      decalPaintable.ApplyDecal(new HatchBrush(HatchStyle.Plaid, Color.Green));
    }
  }
Run Code Online (Sandbox Code Playgroud)

当然,如果paintable没有实现IDecalPaintable,这将抛出.它立即引入了IPainter实现与其操作的IPaintable之间的耦合.但是我也认为说AwesomeDecalPainter不是IPainter是不合理的,因为它的使用仅限于IPaintable域的一个子集.

所以我的问题实际上是四方面的:

  • 接口是否兼容多态?
  • 实现可以在IDecalPaintable上运行的IPainter是一个好的设计吗?
  • 如果它可以专门在IDecalPaintable上运行呢?
  • 是否有任何文献或源代码可以说明接口和多态类型应如何交互?

.net c# oop polymorphism interface

22
推荐指数
4
解决办法
9919
查看次数

有选择地禁用Scala中的包含?(正确输入List.contains)

List("a").contains(5)
Run Code Online (Sandbox Code Playgroud)

因为a Int永远不会包含在列表中String,所以这应该在编译时生成错误,但事实并非如此.

它浪费并默默地测试String列表中包含的每个内容的相等性5,这些内容永远不会成立(在Scala中"5"永远不等于5).

这被称为" '包含'问题 ".而一些人暗示,如果一个类型系统无法正确地输入这样的语义,那么为什么要经过强制执行类型的额外的努力.所以我认为这是一个需要解决的重要问题.

类型参数化B >: AList.contains输入的任何类型的是该类型的超类型A(包含在列表中的元素的类型).

trait List[+A] {
   def contains[B >: A](x: B): Boolean
}
Run Code Online (Sandbox Code Playgroud)

此类型参数化是必要的,因为+A声明列表在类型上是协变A,因此A不能在逆变位置中使用,即作为输入参数的类型.协变列表(必须是不可变的)对于扩展比强制列表(可以是可变的)更强大.

AString在上面的例子有问题,但Int不是的超类型String,所以发生了什么事?该隐含包容 Scala中,决定Any是两者的相互超StringInt.

Scala的创建者Martin Odersky 建议修复将限制输入类型B仅限于那些具有equals方法的类型Any.

trait List[+A] …
Run Code Online (Sandbox Code Playgroud)

scala contains list covariance implicit-cast

22
推荐指数
3
解决办法
1162
查看次数

编程语言中的协方差和逆变

谁能解释我,编程语言理论中协方差和逆变的概念?

c# c++ java programming-languages covariance

20
推荐指数
5
解决办法
5758
查看次数

何时适合使用虚拟方法?

我知道虚方法允许派生类重写从基类继承的方法.何时使用虚拟方法是否合适/不合适?并不总是知道一个班级是否会被分类.一切都应该是虚拟的,只是"以防万一?" 或者这会导致很大的开销吗?

c++ oop methods virtual

20
推荐指数
3
解决办法
5933
查看次数

如何将SOLID原则实现到现有项目中

我为这个问题的主观性而道歉,但我有点卡住了,我希望以前能够处理这个问题的人提供一些指导和建议:

我有(成为什么)一个用C#2.0编写的非常大的RESTful API项目,我的一些类变得非常可怕.我的主要API类就是一个例子 - 有几十个成员和方法(可能接近数百个).你可以想象,它变成了一个小噩梦,不仅仅是维护这段代码,甚至只是导航代码已经成为一件苦差事.

我是SOLID原则的新手,我是设计模式的忠实粉丝(但我仍处于可以实现它们的那个阶段,但还不足以知道何时使用它们 - 在不太明显的情况下) .

我需要打破我的班级规模,但我不知道如何最好地去做.我的StackOverflower伙伴能否建议他们采用现有的代码单块并将其缩小到适当大小?

c# design-patterns solid-principles

18
推荐指数
1
解决办法
4161
查看次数

如何对子类进行单元测试

单元测试子类的最佳方法是什么?让我们假设有一个我已经编写过测试的基类,并且有一些子类会覆盖父公共和/或受保护方法中的一些父行为.

我的子类的测试类是否应该扩展(并在适当的情况下覆盖测试方法)我的基类的测试类,以便应用所有基类测试?否则,我希望有重复的测试代码.

tdd phpunit unit-testing

15
推荐指数
2
解决办法
4687
查看次数