简体   繁体   English

避免从基类继承所有东西

[英]Avoiding Inheriting All Things from Base Class

I was thinking a scenario like that : 我在想这样的场景:

class Utopia => A Base Class which pass it's fields and methods to derived classes. class Utopia => 一个基类,它将其字段和方法传递给派生类。

class Watashi => A derived class, derived from Utopia and inherits everything class Watashi => 从Utopia派生的派生类,并继承所有内容

class Baka => A derived Class, Inherits some fields from Utopia class Baka => 派生类,从Utopia继承一些字段

There are some types above and Type Baka should inherit some specific fields and methods but how ? 上面有一些类型,Baka类型应该继承一些特定的字段和方法,但是如何继承呢? How can I specify fields and methods that only Baka will inherits whereas Watashi inherits everything from Utopia. 如何指定仅Baka会继承而Watashi则从Utopia继承一切的字段和方法。

Sample Code : 样例代码:

class Utopia {
   public string Moshi;

   [Exclude(ClassName("Baka"))]
   public string HaveIt;
}

class Baka : Utopia 
{
 // only Moshi appears here
 base.[Moshi]
}

class Watashi : Utopia 
{
  base.[Moshi][HaveIt];
}

If I want to use Polymorphism : 如果我想使用多态:

   Utopia _utopiaBaka = new Baka();
   _utop.[Moshi];

   Utopia _utopiaWatashi = new Watashi();
   _utopiaWatashi.[Moshi][HaveIt];

And of course Framework also checks the derived class whether they are base classes for other types. 当然,Framework还会检查派生类是否为其他类型的基类。

Split Utopia into more than one class. 将乌托邦分为多个类别。 Have one class that any class can inherit from, so Baka would inherit from that. 有一个可以从任何类继承的类,因此Baka将从那里继承。

Then, extend this PartialUtopia class, add the rest of the methods and have Watashi inherit from that. 然后,扩展此PartialUtopia类,添加其余方法,并让Watashi从该类继承。

This way you can have a way to have classes pick which methods they need by which base class they extend. 这样,您可以让类通过扩展的基类选择所需的方法。

Thats not how inheritance works in OOP. 那不是继承在OOP中的工作方式。 Baka inherits everything from Utopia just like Watashi. Baka像Watashi一样继承了Utopia的一切。

This is not how inheritance works, you would have to split up your classes. 继承不是这样工作的,您必须拆分您的类。 If you and your girlfriend get a child, you can't chose that it only inherits genes for blue eyes and a musculus body :) 如果您和您的女友生了一个孩子,您将无法选择仅继承蓝眼睛和小肌体的基因:)

I would suggest researching the differences between public , private , and protected . 我建议研究一下公共私人受保护之间的区别。 It sounds like that whats your looking for. 听起来像是您要寻找的东西。

http://msdn.microsoft.com/en-us/library/ms173149.aspx http://msdn.microsoft.com/en-us/library/ms173149.aspx

What you want to do is completely incompatible with the concept of inheritance in Object Oriented programming. 您要执行的操作与面向对象编程中的继承概念完全不兼容。 It is like asking "Why is blue blue?" 就像问“为什么是蓝色的蓝色?” if blue was not blue it would not be blue. 如果蓝色不是蓝色,则不会是蓝色。

When one class (Baka) inherits from another (Utopia) this means (in OOP) that Baka can do everything that Utopia can - OOP languages offer features that rely upon this and if you were able to override you would cause horrible exceptions. 当一个类(Baka)从另一个类(Utopia)继承时,这意味着(在OOP中)Baka可以完成Utopia可以做的所有事情-OOP语言提供了依赖于此的功能,如果您能够覆盖它,则将导致可怕的异常。

For example, if I have a method that takes a class of type Utopia as a paramter as below: 例如,如果我有一个将Utopia类型的类作为参数的方法,如下所示:

public void TakesUtopia(Utopia utopia)
{
    utopia.BePerfect();
}

We can also pass in classes of type Watashi and type Baka because they both inherit from Utopia. 我们也可以传入Watashi类型和Baka类型的类,因为它们都继承自Utopia。 Baka, by inheriting from Utopia is guaranteed to have an implementation of the method BePerfect() 通过从Utopia继承,Baka保证具有BePerfect()方法的实现

If somehow an instance of Baka did not have an implementation something horrible would happen. 如果不知何故,Baka实例没有实现,则会发生可怕的事情。

To further this - consider what happens when TakesUtopia relies upon the behaviour of Utopia. 为了进一步做到这一点-考虑一下TakesUtopia依赖于Utopia的行为时会发生什么。 Say for example utopia exposes a PriceOfHappiness property. 假设乌托邦公开了PriceOfHappiness属性。

public string TakesUtopia(Utopia utopia)
{
     if (utopia.PriceOfHappiness() > 100)
     {
          return "Can't buy happiness';
     }
}

When writing my TakesUtopia method, should I be expected to write code to deal with the possiblity that any method within utopia is not implemented? 在编写TakesUtopia方法时,是否应该期望我编写代码来处理乌托邦内部未实现任何方法的可能性? What would such methods do when they are called? 当这些方法被调用时会做什么?

What are you trying to do specifically? 您要具体做什么? If you are concerned about a subclass overriding a given method implementation, you can always declare a method sealed : 如果您担心子类会覆盖给定的方法实现,则始终可以声明一个密封的方法:

class FooBase
{
    sealed void Bar()
    {
        //base implementation
    }
}

class FooDerived
{
    void Bar()  //poof! compilation error
    {
        //never reached
    }
}

Alternatively, you can have your inheriting subclass inside the assembly and the non-inherting outside. 另外,您可以将继承的子类放在程序集中,而非继承的外部。 Just use protected internal . 只需使用protected internal

There's two different concepts: interfaces and inheritance. 有两个不同的概念:接口和继承。 Basically they're two different questions. 基本上,这是两个不同的问题。 One is "How do I want to interact with this object?" 一个是“我如何与该对象交互?” (interface). (接口)。 The second is "How does this object work internally?" 第二个是“该对象如何在内部工作?” (inheritance). (遗产)。

In classic OOP examples, consider a base class: 在经典的OOP示例中,请考虑一个基类:

class Shape {
    virtual void draw();
    virtual int size();
}

This is an interface, it defines how you work with different shapes. 这是一个界面,它定义了如何使用不同的形状。 Now consider these: 现在考虑这些:

class Square : Shape {
    ...
}

class Circle : Shape {
    ...
}

While the interfaces to these two classes would be the same (draw() and size()), the implementations would not share anything in common. 尽管这两个类的接口是相同的(draw()和size()),但是实现不会共享任何共同点。 Is the drawing code for a circle really relevant at all to the drawing code for a Square? 圆的绘图代码与Square的绘图代码真的相关吗? No, they just share the same name & desired result. 不,他们只是使用相同的名称和期望的结果。

The reason I bring this up is because if you want some classes to inherit some members of other classes, then you may have the problem that you're confusing inheritance with interfaces. 之所以提出这一点,是因为如果您希望某些类继承其他类的某些成员,那么您可能会遇到将继承与接口混淆的问题。 AFAIK, C++ doesn't support interfaces (I'm probably wrong about this). AFAIK,C ++不支持接口(对此我可能是错的)。 But you could fake this with 'pure virtual' classes (like the Shape above). 但是您可以使用“纯虚拟”类(例如上面的Shape)来进行伪造。

class Shape {
    virtual void draw();
}

class EdgyShape : Shape {
    virtual int width();
    virtual int height();
}

class RoundyShape : Shape {
    virtual int radius();
}

Now you have interfaces with a heirarchy, but no implementation at all. 现在您有了具有层次结构的接口,但是根本没有实现。

class Circle : RoundyShape {
    ...
}

class Rectangle : EdgyShape {
    ...
}

class Square : Rectangle {
    ...
}

So Circle and Rectangle share no code with each other, while Rectangle and Square do. 因此,Circle和Rectangle彼此不共享代码,而Rectangle和Square则不共享。 And all 3 share the same basic Shape interface, with some additions depending on the type. 所有这3个共享相同的基本Shape接口,并根据类型进行一些补充。

Maybe this sheds light on how to refactor your class heirarchy so you can split them up better? 也许这揭示了如何重构班级层次结构,以便您可以更好地进行拆分?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM