我不明白基类的继承

问题描述

我对继承的理解非常基础。

我想创建一个实现 Idisposable 的基类,然后让其他具有功能的类从该基类继承,以便它们共享一个基类型。

它可以让我把每个对象都放在一个列表中,这样我就可以在我想清理的时候一次性处理掉所有东西。 问题是,C# 中的类只能继承一次,否则只能使用接口。

现在,像 Thread 这样的类如何从我的基类继承而无需我重新编写 Thread 类的基本代码

这听起来可能很愚蠢,但简而言之:我想让已经存在的类继承我选择的基类,而不会失去其功能。 (这样一个项目中使用的所有类都有一个共同的基础,总结为一种对象类型,例如List

这可能吗?

解决方法

如果您的目标是简单地存储可以处理的对象列表,那么您需要一个 List<IDisposable>。任何直接或间接实现该接口的类都可以存储在其中。

var disposables = new List<IDisposable>();
disposables.Add(new MyClass1());
disposables.Add(new SomeClass());
disposables.Add(new AnotherClass());

disposables.ForEach(d => d.Dispose());

这是否是一个有价值的模式,我不相信!

,

例如你给出的 invlolves 接口 IDisposable。在 C# 中,类可以实现多个接口。

另一方面,在 C# 中,类可以从恰好一个类继承。

话虽如此,从类继承并不总是一个好主意,因为它非常有限。相反,我建议组合:wiki

例如,我会建议像组合设计模式这样的东西(这是一个很小的变化,因为组合没有对象集合,而只有一个对象):

public interface IFoo
{
    void DoFooStuff();
}

public class Foo : IFoo
{
    public void DoFooStuff() {...};
}

public class ShouldImplementFoo : IFoo
{
    // Composition,you need to initialize it some time
    private Foo _foo;
    
    public void DoFooStuff() { _foo.DoFooStuff(); }
}

编辑

重新思考您的问题后,您似乎想将一些(不同类别的)对象集合放在一个列表中,以便您可以对列表中的每个对象执行一些定义的操作。 >

最简单的是:用你定义的动作定义接口:

public interface IMyIntf
{
    void MyDesiredAction();
}

现在,让所有的类都实现它。现在你可能会想“好吧,现在我需要在任何地方实现这个方法......” - 没有像那样的!只需使用适配器设计模式,例如,具有类:

public class MyConcreteClass
{
    public void ActionIWishToExecuteOnThisObject() 
    { ... }
}

您只需将其修改为:

public class MyConcreteClass : IMyIntf
{
    public void ActionIWishToExecuteOnThisObject() 
    { ... }

    // implement interface
    public void MyDesiredAction()
    {
        ActionIWishToExecuteOnThisObject();
    }
}

现在,您可以使用一些聚合,例如 List<IMyIntf>,将您感兴趣的所有对象放在那里,然后执行:

foreach(var item in myList)
    item.MyDesiredAction();
,

一个类可以继承自一个祖先类(否则 Object,所有的根)。

它也可以实现一些接口(或不实现)。

一个类可以具有抽象的未实现成员,因此该类是抽象的。

成员也可以是虚拟的以启用多态(抽象成员是)。

一旦实现,一个东西在类中可用,如果不是抽象的,它可以被实例化为真实的,并且对所有子类也可用,除了那些隐藏在子类中的私有的。

无需重复,这是 OOP 的强大功能之一。

这样做,使用抽象、封装、继承和多态,在研究了现实世界和我们工作的领域之后,我们可以设计这个现实世界的投影,我们脑海中的一个视图,概念有数据(字段和属性)和操作(方法),归入工件(对象)以及关系、组合、聚合、接口、组件、控件等。

因此我们可以将处理分解为不重复,例如:

  • Animal 类和 CatDog 子类,
  • 我们将 SizeColor 方面放入动物中,
  • 以及为所有动物实现的 EatWalk 方法,
  • 还有一个抽象的未实现的 DoSound

因此:

  • 在具体的类 CatDog 中,我们不再实现这些东西,
  • 除了 DoSound 是针对每个真实动物性别的。

关于接口,它们是虚拟合同。

例如,我们可以拥有没有共同点的动物和建筑物,乍一看(我们不会回到原子和光子),但我们也希望能够管理猫和狗等对象的实例作为房子和博物馆拍照。

为了实现我们定义了一个接口 IPhotoTaking,并且在定义以前的类时,我们添加了它们实现了这个接口。

代码示例:

public interface IPhotoTaking
{
  Image TakePhoto();
}
public abstract class Animal : IPhotoTaking
{
  public int Size { get; set; }
  public Color Color { get; set; }
  public void Eat() { ... }
  public void Walk() { ... }
  public abstract void DoSOund();
  public Image TakePhoto();
}

public class Cat : Animal // no need to repeat IPhotoTaking
{
  public override void DoSound() { ... }
}

public class Dog : Animal
{
  public override void DoSound() { ... }
}
public abstract class Building :IPhotoTaking
{
  public Image TakePhoto();
}

public class House : Building
{
}

public class Museum : Building
{
}

现在有了这个列表,我们可以像这样使用多态:

var animals = new List<Animal>();

foreach ( var animal in animals )
  animal.DoSound();

也没有多态性,并且因为 C# 不支持真正的多态性,菱形运算符还应用于 List<> 此处,我们可以使用这样的接口:

var items = new List<IPhotoTaking>();

foreach ( var item in items )
  item.TakePhoto();

备注:如果每种类型的拍照可能会有所不同,我们可以将其设置为虚拟以专门针对每种类型进行实现。

OOP Basic Principles

What is abstraction in C#?

How to choose between public,private and protected access modifier?

Association,Composition and Aggregation

What is polymorphism?

What is the difference between an interface and a class?

About the lack of true generic polymorphism and the missing diamond operator in C#

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...