繁体   English   中英

接口方法的签名包括一个class,它实现了接口本身

[英]Signature of interface's method includes a class, which implements the interface itself

考虑到良好的 OOP 和设计的规则,在具有作为输入类型的接口或实现该接口的 output 类型类的接口中编写方法是否正确?

我给你一个关于复数我必须做的非常简单的练习的例子:

public interface IComplex
{
    double GetImaginary();

    double GetReal();
    
    ComplexImpl Conjugate();

    ComplexImpl Add(ComplexImpl y);

}

/*----------------------------------------------------*/


public class ComplexImpl : IComplex
    {
    private double real;

    private double imaginary;

    public ComplexImpl(double real, double imaginary) { this.real = real; this.imaginary = imaginary; }

    public double GetReal() { return this.real; }

    public double GetImaginary() { return this.imaginary; }

    public ComplexImpl Conjugate()
    {
        ComplexImpl conjugate = new ComplexImpl(this.real, -this.imaginary);
        return conjugate;
    }

    public ComplexImpl Add(ComplexImpl y)
    {
        ComplexImpl result = new ComplexImpl(this.real + y.real, this.imaginary + y.imaginary);
        return result;

    }

}

考虑IComplex接口:编写ConjugateAdd方法是否正确,以便它们具有作为 class ComplexImpl 实例化的输入(和/或输出)对象?

考虑到 class ComplexImpl 在定义此方法时实现接口。

编辑

对于那些回答的人:首先谢谢你,但是我有以下问题。 如果我在接口和 class 中将“ComplexImpl”替换为“IComplex”,则会在Add方法中出现此错误:

‘IComplex’不包含‘imaginary’的定义,并且找不到接受‘IComplex’类型的第一个参数的可访问扩展方法‘imaginary’ ”。

解决这个问题的唯一方法是通过使用 Generics?

我建议你在接口中使用接口 IComplex 而不是 ComplexImpl。 这仍然会产生所需的结果,而不依赖于接口的实现。

public interface IComplex
{
    double GetImaginary();

    double GetReal();
    
    IComplex Conjugate();

    IComplex Add(IComplex y);

}

这将是您的具体类型实现:


        public class ComplexImpl : IComplex
        {
            private double real;

            private double imaginary;

            public ComplexImpl(double real, double imaginary) { this.real = real; this.imaginary = imaginary; }

            public double GetReal() { return this.real; }

            public double GetImaginary() { return this.imaginary; }

            public IComplex Conjugate()
            {
                ComplexImpl conjugate = new ComplexImpl(this.real, -this.imaginary);
                return conjugate;
            }

            public IComplex Add(IComplex y)
            {
                ComplexImpl result = new ComplexImpl(this.real + y.GetReal(), this.imaginary + y.GetImaginary());
                return result;

            }

        }

请注意,引用接口时不能访问私有成员。 所有接口定义都是public的。 因此,您不能使用y.imaginary例如,但由于接口为此私有字段GetImaginary()定义了一个访问器,您可以使用它。

这件事打破了使用接口的原因:抽象实现。 一个简单且可以忍受的解决方法是:

public interface IComplex
{
   double GetImaginary();

   double GetReal();

   IComplex Conjugate();

   IComplex Add(IComplex y);

}

这种方式返回一个实现,但接口保持干净并且不了解实现。

您可以使接口或方法成为通用的,约束在您的接口上。

选择 1

public interface IComplex<TComplex>
    where TComplex : IComplex
{
    double GetImaginary();

    double GetReal();
    
    TComplex Conjugate();

    TComplex Add(TComplex y);
}

选择 2

public interface IComplex
{
    double GetImaginary();

    double GetReal();
    
    TComplex Conjugate<TComplex>() where TComplex : IComplex;

    TComplext Add<TComplex>(TComplex y) where TComplex : IComplex;
}

我认为更好的设计是在接口的方法签名中使用IComplex

public interface IComplex
{   
    double GetImaginary();

    double GetReal();


    // Changed:
    
    IComplex Conjugate();

    IComplex Add(IComplex y);
}

并在 Conjuate( Conjuate()和 Add() 中调用.GetReal().GetImaginary() (而不是直接获取realimaginary Add()

public class ComplexImpl : IComplex
{
    private double real;

    private double imaginary;

    public ComplexImpl(double real, double imaginary)
    {
        this.real = real;
        this.imaginary = imaginary;
    }

    public double GetReal() { return this.real; }

    public double GetImaginary() { return this.imaginary; }


    // Changed:

    public IComplex Conjugate()
    {
        ComplexImpl conjugate = new ComplexImpl(this.GetReal(), -this.GetImaginary());

        return conjugate;
    }

    public IComplex Add(IComplex y)
    {
        ComplexImpl result = new ComplexImpl(
            this.GetReal() + y.GetReal(), this.GetImaginary() + y.GetImaginary());

        return result;
    }
}

暂无
暂无

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

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